blob: 744afae619314c57913fdb09bfff35cc2ff20353 [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. Padovan89bc500e2011-06-03 00:19:47 -0300227{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200228 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100229 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200230
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300231 chan->state = state;
Gustavo Padovan53f52122013-10-15 19:24:45 -0300232 chan->ops->state_change(chan, state, 0);
Gustavo F. Padovan89bc500e2011-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. Padovan89bc500e2011-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. Padovan89bc500e2011-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. Padovan89bc500e2011-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
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300620static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan)
621{
622 struct l2cap_conn *conn = chan->conn;
623 struct l2cap_le_conn_rsp rsp;
624 u16 result;
625
626 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
627 result = L2CAP_CR_AUTHORIZATION;
628 else
629 result = L2CAP_CR_BAD_PSM;
630
631 l2cap_state_change(chan, BT_DISCONN);
632
633 rsp.dcid = cpu_to_le16(chan->scid);
634 rsp.mtu = cpu_to_le16(chan->imtu);
635 rsp.mps = __constant_cpu_to_le16(L2CAP_LE_DEFAULT_MPS);
636 rsp.credits = __constant_cpu_to_le16(L2CAP_LE_MAX_CREDITS);
637 rsp.result = cpu_to_le16(result);
638
639 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
640 &rsp);
641}
642
Johan Hedberg791d60f2013-05-14 22:24:44 +0300643static void l2cap_chan_connect_reject(struct l2cap_chan *chan)
644{
645 struct l2cap_conn *conn = chan->conn;
646 struct l2cap_conn_rsp rsp;
647 u16 result;
648
649 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
650 result = L2CAP_CR_SEC_BLOCK;
651 else
652 result = L2CAP_CR_BAD_PSM;
653
654 l2cap_state_change(chan, BT_DISCONN);
655
656 rsp.scid = cpu_to_le16(chan->dcid);
657 rsp.dcid = cpu_to_le16(chan->scid);
658 rsp.result = cpu_to_le16(result);
659 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
660
661 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
662}
663
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300664void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300665{
666 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300667
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700668 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300669
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300670 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300671 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100672 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300673 break;
674
675 case BT_CONNECTED:
676 case BT_CONFIG:
Johan Hedbergcea04ce32013-05-14 22:46:01 +0300677 /* ATT uses L2CAP_CHAN_CONN_ORIENTED so we must also
678 * check for chan->psm.
679 */
680 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && chan->psm) {
Gustavo Padovan8d836d72013-10-15 19:24:47 -0300681 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200682 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300683 } else
684 l2cap_chan_del(chan, reason);
685 break;
686
687 case BT_CONNECT2:
Johan Hedberg791d60f2013-05-14 22:24:44 +0300688 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED) {
689 if (conn->hcon->type == ACL_LINK)
690 l2cap_chan_connect_reject(chan);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300691 else if (conn->hcon->type == LE_LINK)
692 l2cap_chan_le_connect_reject(chan);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300693 }
694
695 l2cap_chan_del(chan, reason);
696 break;
697
698 case BT_CONNECT:
699 case BT_DISCONN:
700 l2cap_chan_del(chan, reason);
701 break;
702
703 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100704 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300705 break;
706 }
707}
708
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300709static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530710{
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700711 switch (chan->chan_type) {
712 case L2CAP_CHAN_RAW:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300713 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530714 case BT_SECURITY_HIGH:
715 return HCI_AT_DEDICATED_BONDING_MITM;
716 case BT_SECURITY_MEDIUM:
717 return HCI_AT_DEDICATED_BONDING;
718 default:
719 return HCI_AT_NO_BONDING;
720 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700721 break;
Marcel Holtmann3124b842013-10-12 07:19:32 -0700722 case L2CAP_CHAN_CONN_LESS:
723 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_3DSP)) {
724 if (chan->sec_level == BT_SECURITY_LOW)
725 chan->sec_level = BT_SECURITY_SDP;
726 }
727 if (chan->sec_level == BT_SECURITY_HIGH)
728 return HCI_AT_NO_BONDING_MITM;
729 else
730 return HCI_AT_NO_BONDING;
731 break;
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700732 case L2CAP_CHAN_CONN_ORIENTED:
733 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
734 if (chan->sec_level == BT_SECURITY_LOW)
735 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530736
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700737 if (chan->sec_level == BT_SECURITY_HIGH)
738 return HCI_AT_NO_BONDING_MITM;
739 else
740 return HCI_AT_NO_BONDING;
741 }
742 /* fall through */
743 default:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300744 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530745 case BT_SECURITY_HIGH:
746 return HCI_AT_GENERAL_BONDING_MITM;
747 case BT_SECURITY_MEDIUM:
748 return HCI_AT_GENERAL_BONDING;
749 default:
750 return HCI_AT_NO_BONDING;
751 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700752 break;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530753 }
754}
755
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200756/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200757int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200758{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300759 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100760 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200761
Johan Hedberga17de2f2013-05-14 13:25:37 +0300762 if (conn->hcon->type == LE_LINK)
763 return smp_conn_security(conn->hcon, chan->sec_level);
764
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300765 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100766
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300767 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200768}
769
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200770static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200771{
772 u8 id;
773
774 /* Get next available identificator.
775 * 1 - 128 are used by kernel.
776 * 129 - 199 are reserved.
777 * 200 - 254 are used by utilities like l2ping, etc.
778 */
779
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200780 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200781
782 if (++conn->tx_ident > 128)
783 conn->tx_ident = 1;
784
785 id = conn->tx_ident;
786
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200787 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200788
789 return id;
790}
791
Gustavo Padovan2d792812012-10-06 10:07:01 +0100792static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
793 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200794{
795 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200796 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200797
798 BT_DBG("code 0x%2.2x", code);
799
800 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300801 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200802
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200803 if (lmp_no_flush_capable(conn->hcon->hdev))
804 flags = ACL_START_NO_FLUSH;
805 else
806 flags = ACL_START;
807
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700808 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200809 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700810
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200811 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200812}
813
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700814static bool __chan_is_moving(struct l2cap_chan *chan)
815{
816 return chan->move_state != L2CAP_MOVE_STABLE &&
817 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
818}
819
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200820static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
821{
822 struct hci_conn *hcon = chan->conn->hcon;
823 u16 flags;
824
825 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100826 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200827
Mat Martineaud5f8a752012-10-23 15:24:18 -0700828 if (chan->hs_hcon && !__chan_is_moving(chan)) {
829 if (chan->hs_hchan)
830 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
831 else
832 kfree_skb(skb);
833
834 return;
835 }
836
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200837 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100838 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200839 flags = ACL_START_NO_FLUSH;
840 else
841 flags = ACL_START;
842
843 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
844 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845}
846
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700847static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
848{
849 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
850 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
851
852 if (enh & L2CAP_CTRL_FRAME_TYPE) {
853 /* S-Frame */
854 control->sframe = 1;
855 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
856 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
857
858 control->sar = 0;
859 control->txseq = 0;
860 } else {
861 /* I-Frame */
862 control->sframe = 0;
863 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
864 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
865
866 control->poll = 0;
867 control->super = 0;
868 }
869}
870
871static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
872{
873 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
874 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
875
876 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
877 /* S-Frame */
878 control->sframe = 1;
879 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
880 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
881
882 control->sar = 0;
883 control->txseq = 0;
884 } else {
885 /* I-Frame */
886 control->sframe = 0;
887 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
888 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
889
890 control->poll = 0;
891 control->super = 0;
892 }
893}
894
895static inline void __unpack_control(struct l2cap_chan *chan,
896 struct sk_buff *skb)
897{
898 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
899 __unpack_extended_control(get_unaligned_le32(skb->data),
900 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700901 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700902 } else {
903 __unpack_enhanced_control(get_unaligned_le16(skb->data),
904 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700905 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700906 }
907}
908
909static u32 __pack_extended_control(struct l2cap_ctrl *control)
910{
911 u32 packed;
912
913 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
914 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
915
916 if (control->sframe) {
917 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
918 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
919 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
920 } else {
921 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
922 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
923 }
924
925 return packed;
926}
927
928static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
929{
930 u16 packed;
931
932 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
933 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
934
935 if (control->sframe) {
936 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
937 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
938 packed |= L2CAP_CTRL_FRAME_TYPE;
939 } else {
940 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
941 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
942 }
943
944 return packed;
945}
946
947static inline void __pack_control(struct l2cap_chan *chan,
948 struct l2cap_ctrl *control,
949 struct sk_buff *skb)
950{
951 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
952 put_unaligned_le32(__pack_extended_control(control),
953 skb->data + L2CAP_HDR_SIZE);
954 } else {
955 put_unaligned_le16(__pack_enhanced_control(control),
956 skb->data + L2CAP_HDR_SIZE);
957 }
958}
959
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300960static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
961{
962 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
963 return L2CAP_EXT_HDR_SIZE;
964 else
965 return L2CAP_ENH_HDR_SIZE;
966}
967
Mat Martineaua67d7f62012-05-17 20:53:35 -0700968static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
969 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300970{
971 struct sk_buff *skb;
972 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300973 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300974
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300975 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300976 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300977
Mat Martineaua67d7f62012-05-17 20:53:35 -0700978 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300979
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300980 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700981 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300982
983 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300984 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300985 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300986
Mat Martineaua67d7f62012-05-17 20:53:35 -0700987 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
988 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
989 else
990 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300991
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300992 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700993 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300994 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300995 }
996
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200997 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700998 return skb;
999}
1000
1001static void l2cap_send_sframe(struct l2cap_chan *chan,
1002 struct l2cap_ctrl *control)
1003{
1004 struct sk_buff *skb;
1005 u32 control_field;
1006
1007 BT_DBG("chan %p, control %p", chan, control);
1008
1009 if (!control->sframe)
1010 return;
1011
Mat Martineaub99e13a2012-10-23 15:24:19 -07001012 if (__chan_is_moving(chan))
1013 return;
1014
Mat Martineaua67d7f62012-05-17 20:53:35 -07001015 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
1016 !control->poll)
1017 control->final = 1;
1018
1019 if (control->super == L2CAP_SUPER_RR)
1020 clear_bit(CONN_RNR_SENT, &chan->conn_state);
1021 else if (control->super == L2CAP_SUPER_RNR)
1022 set_bit(CONN_RNR_SENT, &chan->conn_state);
1023
1024 if (control->super != L2CAP_SUPER_SREJ) {
1025 chan->last_acked_seq = control->reqseq;
1026 __clear_ack_timer(chan);
1027 }
1028
1029 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
1030 control->final, control->poll, control->super);
1031
1032 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1033 control_field = __pack_extended_control(control);
1034 else
1035 control_field = __pack_enhanced_control(control);
1036
1037 skb = l2cap_create_sframe_pdu(chan, control_field);
1038 if (!IS_ERR(skb))
1039 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001040}
1041
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001042static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001043{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001044 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001045
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001046 BT_DBG("chan %p, poll %d", chan, poll);
1047
1048 memset(&control, 0, sizeof(control));
1049 control.sframe = 1;
1050 control.poll = poll;
1051
1052 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
1053 control.super = L2CAP_SUPER_RNR;
1054 else
1055 control.super = L2CAP_SUPER_RR;
1056
1057 control.reqseq = chan->buffer_seq;
1058 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001059}
1060
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001061static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001062{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001063 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001064}
1065
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001066static bool __amp_capable(struct l2cap_chan *chan)
1067{
1068 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001069 struct hci_dev *hdev;
1070 bool amp_available = false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001071
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001072 if (!conn->hs_enabled)
1073 return false;
1074
1075 if (!(conn->fixed_chan_mask & L2CAP_FC_A2MP))
1076 return false;
1077
1078 read_lock(&hci_dev_list_lock);
1079 list_for_each_entry(hdev, &hci_dev_list, list) {
1080 if (hdev->amp_type != AMP_TYPE_BREDR &&
1081 test_bit(HCI_UP, &hdev->flags)) {
1082 amp_available = true;
1083 break;
1084 }
1085 }
1086 read_unlock(&hci_dev_list_lock);
1087
1088 if (chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED)
1089 return amp_available;
Marcel Holtmann848566b2013-10-01 22:59:22 -07001090
1091 return false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001092}
1093
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001094static bool l2cap_check_efs(struct l2cap_chan *chan)
1095{
1096 /* Check EFS parameters */
1097 return true;
1098}
1099
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001100void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001101{
1102 struct l2cap_conn *conn = chan->conn;
1103 struct l2cap_conn_req req;
1104
1105 req.scid = cpu_to_le16(chan->scid);
1106 req.psm = chan->psm;
1107
1108 chan->ident = l2cap_get_ident(conn);
1109
1110 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1111
1112 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1113}
1114
Mat Martineau8eb200b2012-10-23 15:24:17 -07001115static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1116{
1117 struct l2cap_create_chan_req req;
1118 req.scid = cpu_to_le16(chan->scid);
1119 req.psm = chan->psm;
1120 req.amp_id = amp_id;
1121
1122 chan->ident = l2cap_get_ident(chan->conn);
1123
1124 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1125 sizeof(req), &req);
1126}
1127
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001128static void l2cap_move_setup(struct l2cap_chan *chan)
1129{
1130 struct sk_buff *skb;
1131
1132 BT_DBG("chan %p", chan);
1133
1134 if (chan->mode != L2CAP_MODE_ERTM)
1135 return;
1136
1137 __clear_retrans_timer(chan);
1138 __clear_monitor_timer(chan);
1139 __clear_ack_timer(chan);
1140
1141 chan->retry_count = 0;
1142 skb_queue_walk(&chan->tx_q, skb) {
1143 if (bt_cb(skb)->control.retries)
1144 bt_cb(skb)->control.retries = 1;
1145 else
1146 break;
1147 }
1148
1149 chan->expected_tx_seq = chan->buffer_seq;
1150
1151 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1152 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1153 l2cap_seq_list_clear(&chan->retrans_list);
1154 l2cap_seq_list_clear(&chan->srej_list);
1155 skb_queue_purge(&chan->srej_q);
1156
1157 chan->tx_state = L2CAP_TX_STATE_XMIT;
1158 chan->rx_state = L2CAP_RX_STATE_MOVE;
1159
1160 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1161}
1162
Mat Martineau5f3847a2012-10-23 15:24:12 -07001163static void l2cap_move_done(struct l2cap_chan *chan)
1164{
1165 u8 move_role = chan->move_role;
1166 BT_DBG("chan %p", chan);
1167
1168 chan->move_state = L2CAP_MOVE_STABLE;
1169 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1170
1171 if (chan->mode != L2CAP_MODE_ERTM)
1172 return;
1173
1174 switch (move_role) {
1175 case L2CAP_MOVE_ROLE_INITIATOR:
1176 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1177 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1178 break;
1179 case L2CAP_MOVE_ROLE_RESPONDER:
1180 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1181 break;
1182 }
1183}
1184
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001185static void l2cap_chan_ready(struct l2cap_chan *chan)
1186{
Mat Martineau28270112012-05-17 21:14:09 -07001187 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001188 chan->conf_state = 0;
1189 __clear_chan_timer(chan);
1190
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001191 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001192
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001193 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001194}
1195
Johan Hedbergf1496de2013-05-13 14:15:56 +03001196static void l2cap_le_connect(struct l2cap_chan *chan)
1197{
1198 struct l2cap_conn *conn = chan->conn;
1199 struct l2cap_le_conn_req req;
1200
1201 req.psm = chan->psm;
1202 req.scid = cpu_to_le16(chan->scid);
1203 req.mtu = cpu_to_le16(chan->imtu);
1204 req.mps = __constant_cpu_to_le16(L2CAP_LE_DEFAULT_MPS);
1205 req.credits = __constant_cpu_to_le16(L2CAP_LE_MAX_CREDITS);
1206
1207 chan->ident = l2cap_get_ident(conn);
1208
1209 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_REQ,
1210 sizeof(req), &req);
1211}
1212
1213static void l2cap_le_start(struct l2cap_chan *chan)
1214{
1215 struct l2cap_conn *conn = chan->conn;
1216
1217 if (!smp_conn_security(conn->hcon, chan->sec_level))
1218 return;
1219
1220 if (!chan->psm) {
1221 l2cap_chan_ready(chan);
1222 return;
1223 }
1224
1225 if (chan->state == BT_CONNECT)
1226 l2cap_le_connect(chan);
1227}
1228
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001229static void l2cap_start_connection(struct l2cap_chan *chan)
1230{
1231 if (__amp_capable(chan)) {
1232 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1233 a2mp_discover_amp(chan);
Johan Hedbergf1496de2013-05-13 14:15:56 +03001234 } else if (chan->conn->hcon->type == LE_LINK) {
1235 l2cap_le_start(chan);
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001236 } else {
1237 l2cap_send_conn_req(chan);
1238 }
1239}
1240
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001241static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001242{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001243 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001244
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001245 if (conn->hcon->type == LE_LINK) {
Johan Hedberg96ac34f2013-05-13 11:15:07 +03001246 l2cap_le_start(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001247 return;
1248 }
1249
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001250 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001251 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1252 return;
1253
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001254 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001255 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001256 l2cap_start_connection(chan);
1257 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001258 } else {
1259 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001260 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001261
1262 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1263 conn->info_ident = l2cap_get_ident(conn);
1264
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001265 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001266
Gustavo Padovan2d792812012-10-06 10:07:01 +01001267 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1268 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001269 }
1270}
1271
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001272static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1273{
1274 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001275 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001276 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1277
1278 switch (mode) {
1279 case L2CAP_MODE_ERTM:
1280 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1281 case L2CAP_MODE_STREAMING:
1282 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1283 default:
1284 return 0x00;
1285 }
1286}
1287
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001288static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001289{
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001290 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001291 struct l2cap_disconn_req req;
1292
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001293 if (!conn)
1294 return;
1295
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001296 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001297 __clear_retrans_timer(chan);
1298 __clear_monitor_timer(chan);
1299 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001300 }
1301
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001302 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001303 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001304 return;
1305 }
1306
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001307 req.dcid = cpu_to_le16(chan->dcid);
1308 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001309 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1310 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001311
Gustavo Padovanf8e73012013-10-15 19:24:46 -03001312 l2cap_state_change_and_error(chan, BT_DISCONN, err);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001313}
1314
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001316static void l2cap_conn_start(struct l2cap_conn *conn)
1317{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001318 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001319
1320 BT_DBG("conn %p", conn);
1321
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001322 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001323
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001324 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001325 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001326
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001327 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001328 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001329 continue;
1330 }
1331
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001332 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001333 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001334 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001335 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001336 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001337 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001338
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001339 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001340 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001341 &chan->conf_state)) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001342 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001343 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001344 continue;
1345 }
1346
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001347 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001348
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001349 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001350 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001351 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001352 rsp.scid = cpu_to_le16(chan->dcid);
1353 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001354
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001355 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07001356 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001357 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1358 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001359 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001360
1361 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02001362 l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001363 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1364 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001365 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001366 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001367 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1368 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001369 }
1370
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001371 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001372 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001373
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001374 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001375 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001376 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001377 continue;
1378 }
1379
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001380 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001381 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001382 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001383 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001384 }
1385
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001386 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001387 }
1388
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001389 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001390}
1391
Ido Yarivc2287682012-04-20 15:46:07 -03001392/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001393 * Returns closest match, locked.
1394 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001395static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001396 bdaddr_t *src,
1397 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001398{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001399 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001400
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001401 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001402
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001403 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001404 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001405 continue;
1406
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001407 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001408 int src_match, dst_match;
1409 int src_any, dst_any;
1410
Ville Tervob62f3282011-02-10 22:38:50 -03001411 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001412 src_match = !bacmp(&c->src, src);
1413 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001414 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001415 read_unlock(&chan_list_lock);
1416 return c;
1417 }
Ville Tervob62f3282011-02-10 22:38:50 -03001418
1419 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001420 src_any = !bacmp(&c->src, BDADDR_ANY);
1421 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001422 if ((src_match && dst_any) || (src_any && dst_match) ||
1423 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001424 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001425 }
1426 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001427
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001428 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001429
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001430 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001431}
1432
1433static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1434{
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001435 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001436 struct l2cap_chan *chan, *pchan;
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001437 u8 dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001438
1439 BT_DBG("");
1440
1441 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001442 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001443 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001444 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001445 return;
1446
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001447 /* Client ATT sockets should override the server one */
1448 if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
1449 return;
1450
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001451 dst_type = bdaddr_type(hcon, hcon->dst_type);
1452
1453 /* If device is blocked, do not create a channel for it */
1454 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, dst_type))
1455 return;
1456
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001457 l2cap_chan_lock(pchan);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001458
Gustavo Padovan80b98022012-05-27 22:27:51 -03001459 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001460 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001461 goto clean;
1462
Johan Hedberg9f22398c2013-04-29 19:35:38 +03001463 chan->dcid = L2CAP_CID_ATT;
1464
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001465 bacpy(&chan->src, &hcon->src);
1466 bacpy(&chan->dst, &hcon->dst);
1467 chan->src_type = bdaddr_type(hcon, hcon->src_type);
1468 chan->dst_type = dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001469
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001470 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001471
Ville Tervob62f3282011-02-10 22:38:50 -03001472clean:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001473 l2cap_chan_unlock(pchan);
Ville Tervob62f3282011-02-10 22:38:50 -03001474}
1475
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001476static void l2cap_conn_ready(struct l2cap_conn *conn)
1477{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001478 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001479 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001480
1481 BT_DBG("conn %p", conn);
1482
Johan Hedbergd8729922013-04-29 19:35:39 +03001483 /* For outgoing pairing which doesn't necessarily have an
1484 * associated socket (e.g. mgmt_pair_device).
1485 */
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001486 if (hcon->out && hcon->type == LE_LINK)
1487 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001488
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001489 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001490
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001491 if (hcon->type == LE_LINK)
1492 l2cap_le_conn_ready(conn);
1493
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001494 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001495
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001496 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001497
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001498 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1499 l2cap_chan_unlock(chan);
1500 continue;
1501 }
1502
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001503 if (hcon->type == LE_LINK) {
Johan Hedbergf1496de2013-05-13 14:15:56 +03001504 l2cap_le_start(chan);
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001505 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo Padovan74e75742013-10-15 19:24:51 -03001506 l2cap_chan_ready(chan);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001507
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001508 } else if (chan->state == BT_CONNECT) {
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001509 l2cap_do_start(chan);
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001510 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001511
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001512 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001513 }
1514
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001515 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001516}
1517
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001518/* Notify sockets that we cannot guaranty reliability anymore */
1519static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1520{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001521 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001522
1523 BT_DBG("conn %p", conn);
1524
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001525 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001526
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001527 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001528 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001529 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001530 }
1531
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001532 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001533}
1534
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001535static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001536{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001537 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001538 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001539
Marcel Holtmann984947d2009-02-06 23:35:19 +01001540 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001541 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001542
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001543 l2cap_conn_start(conn);
1544}
1545
David Herrmann2c8e1412013-04-06 20:28:45 +02001546/*
1547 * l2cap_user
1548 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1549 * callback is called during registration. The ->remove callback is called
1550 * during unregistration.
1551 * An l2cap_user object can either be explicitly unregistered or when the
1552 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1553 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1554 * External modules must own a reference to the l2cap_conn object if they intend
1555 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1556 * any time if they don't.
1557 */
1558
1559int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1560{
1561 struct hci_dev *hdev = conn->hcon->hdev;
1562 int ret;
1563
1564 /* We need to check whether l2cap_conn is registered. If it is not, we
1565 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1566 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1567 * relies on the parent hci_conn object to be locked. This itself relies
1568 * on the hci_dev object to be locked. So we must lock the hci device
1569 * here, too. */
1570
1571 hci_dev_lock(hdev);
1572
1573 if (user->list.next || user->list.prev) {
1574 ret = -EINVAL;
1575 goto out_unlock;
1576 }
1577
1578 /* conn->hchan is NULL after l2cap_conn_del() was called */
1579 if (!conn->hchan) {
1580 ret = -ENODEV;
1581 goto out_unlock;
1582 }
1583
1584 ret = user->probe(conn, user);
1585 if (ret)
1586 goto out_unlock;
1587
1588 list_add(&user->list, &conn->users);
1589 ret = 0;
1590
1591out_unlock:
1592 hci_dev_unlock(hdev);
1593 return ret;
1594}
1595EXPORT_SYMBOL(l2cap_register_user);
1596
1597void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1598{
1599 struct hci_dev *hdev = conn->hcon->hdev;
1600
1601 hci_dev_lock(hdev);
1602
1603 if (!user->list.next || !user->list.prev)
1604 goto out_unlock;
1605
1606 list_del(&user->list);
1607 user->list.next = NULL;
1608 user->list.prev = NULL;
1609 user->remove(conn, user);
1610
1611out_unlock:
1612 hci_dev_unlock(hdev);
1613}
1614EXPORT_SYMBOL(l2cap_unregister_user);
1615
1616static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1617{
1618 struct l2cap_user *user;
1619
1620 while (!list_empty(&conn->users)) {
1621 user = list_first_entry(&conn->users, struct l2cap_user, list);
1622 list_del(&user->list);
1623 user->list.next = NULL;
1624 user->list.prev = NULL;
1625 user->remove(conn, user);
1626 }
1627}
1628
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001629static void l2cap_conn_del(struct hci_conn *hcon, int err)
1630{
1631 struct l2cap_conn *conn = hcon->l2cap_data;
1632 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001633
1634 if (!conn)
1635 return;
1636
1637 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1638
1639 kfree_skb(conn->rx_skb);
1640
David Herrmann2c8e1412013-04-06 20:28:45 +02001641 l2cap_unregister_all_users(conn);
1642
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001643 mutex_lock(&conn->chan_lock);
1644
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001645 /* Kill channels */
1646 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001647 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001648 l2cap_chan_lock(chan);
1649
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001650 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001651
1652 l2cap_chan_unlock(chan);
1653
Gustavo Padovan80b98022012-05-27 22:27:51 -03001654 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001655 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001656 }
1657
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001658 mutex_unlock(&conn->chan_lock);
1659
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001660 hci_chan_del(conn->hchan);
1661
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001662 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001663 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001664
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001665 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001666 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001667 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001668 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001669
1670 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001671 conn->hchan = NULL;
1672 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001673}
1674
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001675static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001676{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001677 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001678 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001679
Johan Hedbergd06cc412012-06-06 18:44:11 +08001680 BT_DBG("conn %p", conn);
1681
1682 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1683 smp_chan_destroy(conn);
1684 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1685 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001686}
1687
Claudio Takahasibaf43252013-04-11 13:55:50 -03001688static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689{
Marcel Holtmann01394182006-07-03 10:02:46 +02001690 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001691 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692
Claudio Takahasibaf43252013-04-11 13:55:50 -03001693 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694 return conn;
1695
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001696 hchan = hci_chan_create(hcon);
1697 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001700 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001701 if (!conn) {
1702 hci_chan_del(hchan);
1703 return NULL;
1704 }
1705
David Herrmann9c903e32013-04-06 20:28:44 +02001706 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 hcon->l2cap_data = conn;
1708 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001709 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001710 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001712 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001713
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001714 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001715 case LE_LINK:
1716 if (hcon->hdev->le_mtu) {
1717 conn->mtu = hcon->hdev->le_mtu;
1718 break;
1719 }
1720 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001721 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001722 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001723 break;
1724 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001725
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001726 conn->feat_mask = 0;
1727
Marcel Holtmann848566b2013-10-01 22:59:22 -07001728 if (hcon->type == ACL_LINK)
1729 conn->hs_enabled = test_bit(HCI_HS_ENABLED,
1730 &hcon->hdev->dev_flags);
1731
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001733 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001734
1735 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001736 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001738 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001739 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001740 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001741 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001742
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001743 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001744
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 return conn;
1746}
1747
David Herrmann9c903e32013-04-06 20:28:44 +02001748static void l2cap_conn_free(struct kref *ref)
1749{
1750 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1751
1752 hci_conn_put(conn->hcon);
1753 kfree(conn);
1754}
1755
1756void l2cap_conn_get(struct l2cap_conn *conn)
1757{
1758 kref_get(&conn->ref);
1759}
1760EXPORT_SYMBOL(l2cap_conn_get);
1761
1762void l2cap_conn_put(struct l2cap_conn *conn)
1763{
1764 kref_put(&conn->ref, l2cap_conn_free);
1765}
1766EXPORT_SYMBOL(l2cap_conn_put);
1767
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769
Ido Yarivc2287682012-04-20 15:46:07 -03001770/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771 * Returns closest match.
1772 */
Ido Yarivc2287682012-04-20 15:46:07 -03001773static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1774 bdaddr_t *src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001775 bdaddr_t *dst,
1776 u8 link_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001778 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001780 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001781
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001782 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001783 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784 continue;
1785
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001786 if (link_type == ACL_LINK && c->src_type != BDADDR_BREDR)
1787 continue;
1788
1789 if (link_type == LE_LINK && c->src_type == BDADDR_BREDR)
1790 continue;
1791
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001792 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001793 int src_match, dst_match;
1794 int src_any, dst_any;
1795
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001797 src_match = !bacmp(&c->src, src);
1798 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001799 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001800 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001801 return c;
1802 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803
1804 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001805 src_any = !bacmp(&c->src, BDADDR_ANY);
1806 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001807 if ((src_match && dst_any) || (src_any && dst_match) ||
1808 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001809 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810 }
1811 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001813 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001814
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001815 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816}
1817
Andre Guedes8e9f9892012-04-24 21:02:55 -03001818int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1819 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821 struct l2cap_conn *conn;
1822 struct hci_conn *hcon;
1823 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001824 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001825 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001827 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301828 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001830 hdev = hci_get_route(dst, &chan->src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001831 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832 return -EHOSTUNREACH;
1833
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001834 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001836 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001837
1838 /* PSM must be odd and lsb of upper byte must be 0 */
1839 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001840 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001841 err = -EINVAL;
1842 goto done;
1843 }
1844
1845 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1846 err = -EINVAL;
1847 goto done;
1848 }
1849
1850 switch (chan->mode) {
1851 case L2CAP_MODE_BASIC:
1852 break;
1853 case L2CAP_MODE_ERTM:
1854 case L2CAP_MODE_STREAMING:
1855 if (!disable_ertm)
1856 break;
1857 /* fall through */
1858 default:
1859 err = -ENOTSUPP;
1860 goto done;
1861 }
1862
Gustavo Padovan0797e012012-05-27 22:27:54 -03001863 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001864 case BT_CONNECT:
1865 case BT_CONNECT2:
1866 case BT_CONFIG:
1867 /* Already connecting */
1868 err = 0;
1869 goto done;
1870
1871 case BT_CONNECTED:
1872 /* Already connected */
1873 err = -EISCONN;
1874 goto done;
1875
1876 case BT_OPEN:
1877 case BT_BOUND:
1878 /* Can connect */
1879 break;
1880
1881 default:
1882 err = -EBADFD;
1883 goto done;
1884 }
1885
1886 /* Set destination address and psm */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001887 bacpy(&chan->dst, dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001888 chan->dst_type = dst_type;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001889
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001890 chan->psm = psm;
1891 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001892
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001893 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001894
Johan Hedbergf224ca52013-04-29 19:35:36 +03001895 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001896 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001897 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001898 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001899 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001900 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001901
Ville Tervo30e76272011-02-22 16:10:53 -03001902 if (IS_ERR(hcon)) {
1903 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001905 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001906
Claudio Takahasibaf43252013-04-11 13:55:50 -03001907 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001909 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001910 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911 goto done;
1912 }
1913
Johan Hedberg141d5702013-04-29 19:35:37 +03001914 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1915 hci_conn_drop(hcon);
1916 err = -EBUSY;
1917 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001918 }
1919
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920 /* Update source addr of the socket */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001921 bacpy(&chan->src, &hcon->src);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001922 chan->src_type = bdaddr_type(hcon, hcon->src_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001923
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001924 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001925 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001926 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001927
Johan Hedberg5ee98912013-04-29 19:35:43 +03001928 /* l2cap_chan_add takes its own ref so we can drop this one */
1929 hci_conn_drop(hcon);
1930
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001931 l2cap_state_change(chan, BT_CONNECT);
Gustavo Padovan8d836d72013-10-15 19:24:47 -03001932 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933
1934 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001935 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001936 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001937 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001938 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001939 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001940 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001941 }
1942
Ville Tervo30e76272011-02-22 16:10:53 -03001943 err = 0;
1944
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001946 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001947 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948 hci_dev_put(hdev);
1949 return err;
1950}
1951
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001952static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001953{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001954 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001955 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001956
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001957 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001958
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001959 l2cap_chan_lock(chan);
1960
Mat Martineau80909e02012-05-17 20:53:50 -07001961 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001962 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001963 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001964 return;
1965 }
1966
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001967 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001968
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001969 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001970 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001971}
1972
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001973static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001974{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001975 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001976 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001977
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001978 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001979
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001980 l2cap_chan_lock(chan);
1981
Mat Martineau80909e02012-05-17 20:53:50 -07001982 if (!chan->conn) {
1983 l2cap_chan_unlock(chan);
1984 l2cap_chan_put(chan);
1985 return;
1986 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001987
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001988 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001989 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001990 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001991}
1992
Gustavo Padovand6603662012-05-21 13:58:22 -03001993static void l2cap_streaming_send(struct l2cap_chan *chan,
1994 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001995{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001996 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001997 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001998
Mat Martineau37339372012-05-17 20:53:33 -07001999 BT_DBG("chan %p, skbs %p", chan, skbs);
2000
Mat Martineaub99e13a2012-10-23 15:24:19 -07002001 if (__chan_is_moving(chan))
2002 return;
2003
Mat Martineau37339372012-05-17 20:53:33 -07002004 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2005
2006 while (!skb_queue_empty(&chan->tx_q)) {
2007
2008 skb = skb_dequeue(&chan->tx_q);
2009
2010 bt_cb(skb)->control.retries = 1;
2011 control = &bt_cb(skb)->control;
2012
2013 control->reqseq = 0;
2014 control->txseq = chan->next_tx_seq;
2015
2016 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002017
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002018 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07002019 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2020 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002021 }
2022
Gustavo F. Padovan43434782011-04-12 18:31:57 -03002023 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002024
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002025 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07002026
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002027 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07002028 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002029 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002030}
2031
Szymon Janc67c9e842011-07-28 16:24:33 +02002032static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002033{
2034 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07002035 struct l2cap_ctrl *control;
2036 int sent = 0;
2037
2038 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002039
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03002040 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03002041 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002042
Mat Martineau94122bb2012-05-02 09:42:02 -07002043 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2044 return 0;
2045
Mat Martineaub99e13a2012-10-23 15:24:19 -07002046 if (__chan_is_moving(chan))
2047 return 0;
2048
Mat Martineau18a48e72012-05-17 20:53:34 -07002049 while (chan->tx_send_head &&
2050 chan->unacked_frames < chan->remote_tx_win &&
2051 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002052
Mat Martineau18a48e72012-05-17 20:53:34 -07002053 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002054
Mat Martineau18a48e72012-05-17 20:53:34 -07002055 bt_cb(skb)->control.retries = 1;
2056 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03002057
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002058 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07002059 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002060
Mat Martineau18a48e72012-05-17 20:53:34 -07002061 control->reqseq = chan->buffer_seq;
2062 chan->last_acked_seq = chan->buffer_seq;
2063 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002064
Mat Martineau18a48e72012-05-17 20:53:34 -07002065 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002066
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002067 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07002068 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2069 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002070 }
2071
Mat Martineau18a48e72012-05-17 20:53:34 -07002072 /* Clone after data has been modified. Data is assumed to be
2073 read-only (for locking purposes) on cloned sk_buffs.
2074 */
2075 tx_skb = skb_clone(skb, GFP_KERNEL);
2076
2077 if (!tx_skb)
2078 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002079
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002080 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002081
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002082 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002083 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002084 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002085 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002086
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002087 if (skb_queue_is_last(&chan->tx_q, skb))
2088 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002089 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002090 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002091
2092 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002093 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002094 }
2095
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002096 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2097 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002098
2099 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002100}
2101
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002102static void l2cap_ertm_resend(struct l2cap_chan *chan)
2103{
2104 struct l2cap_ctrl control;
2105 struct sk_buff *skb;
2106 struct sk_buff *tx_skb;
2107 u16 seq;
2108
2109 BT_DBG("chan %p", chan);
2110
2111 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2112 return;
2113
Mat Martineaub99e13a2012-10-23 15:24:19 -07002114 if (__chan_is_moving(chan))
2115 return;
2116
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002117 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2118 seq = l2cap_seq_list_pop(&chan->retrans_list);
2119
2120 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2121 if (!skb) {
2122 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002123 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002124 continue;
2125 }
2126
2127 bt_cb(skb)->control.retries++;
2128 control = bt_cb(skb)->control;
2129
2130 if (chan->max_tx != 0 &&
2131 bt_cb(skb)->control.retries > chan->max_tx) {
2132 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002133 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002134 l2cap_seq_list_clear(&chan->retrans_list);
2135 break;
2136 }
2137
2138 control.reqseq = chan->buffer_seq;
2139 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2140 control.final = 1;
2141 else
2142 control.final = 0;
2143
2144 if (skb_cloned(skb)) {
2145 /* Cloned sk_buffs are read-only, so we need a
2146 * writeable copy
2147 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002148 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002149 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002150 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002151 }
2152
2153 if (!tx_skb) {
2154 l2cap_seq_list_clear(&chan->retrans_list);
2155 break;
2156 }
2157
2158 /* Update skb contents */
2159 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2160 put_unaligned_le32(__pack_extended_control(&control),
2161 tx_skb->data + L2CAP_HDR_SIZE);
2162 } else {
2163 put_unaligned_le16(__pack_enhanced_control(&control),
2164 tx_skb->data + L2CAP_HDR_SIZE);
2165 }
2166
2167 if (chan->fcs == L2CAP_FCS_CRC16) {
2168 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2169 put_unaligned_le16(fcs, skb_put(tx_skb,
2170 L2CAP_FCS_SIZE));
2171 }
2172
2173 l2cap_do_send(chan, tx_skb);
2174
2175 BT_DBG("Resent txseq %d", control.txseq);
2176
2177 chan->last_acked_seq = chan->buffer_seq;
2178 }
2179}
2180
Mat Martineauf80842a2012-05-17 20:53:46 -07002181static void l2cap_retransmit(struct l2cap_chan *chan,
2182 struct l2cap_ctrl *control)
2183{
2184 BT_DBG("chan %p, control %p", chan, control);
2185
2186 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2187 l2cap_ertm_resend(chan);
2188}
2189
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002190static void l2cap_retransmit_all(struct l2cap_chan *chan,
2191 struct l2cap_ctrl *control)
2192{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002193 struct sk_buff *skb;
2194
2195 BT_DBG("chan %p, control %p", chan, control);
2196
2197 if (control->poll)
2198 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2199
2200 l2cap_seq_list_clear(&chan->retrans_list);
2201
2202 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2203 return;
2204
2205 if (chan->unacked_frames) {
2206 skb_queue_walk(&chan->tx_q, skb) {
2207 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002208 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002209 break;
2210 }
2211
2212 skb_queue_walk_from(&chan->tx_q, skb) {
2213 if (skb == chan->tx_send_head)
2214 break;
2215
2216 l2cap_seq_list_append(&chan->retrans_list,
2217 bt_cb(skb)->control.txseq);
2218 }
2219
2220 l2cap_ertm_resend(chan);
2221 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002222}
2223
Szymon Jancb17e73b2012-01-11 10:59:47 +01002224static void l2cap_send_ack(struct l2cap_chan *chan)
2225{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002226 struct l2cap_ctrl control;
2227 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2228 chan->last_acked_seq);
2229 int threshold;
2230
2231 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2232 chan, chan->last_acked_seq, chan->buffer_seq);
2233
2234 memset(&control, 0, sizeof(control));
2235 control.sframe = 1;
2236
2237 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2238 chan->rx_state == L2CAP_RX_STATE_RECV) {
2239 __clear_ack_timer(chan);
2240 control.super = L2CAP_SUPER_RNR;
2241 control.reqseq = chan->buffer_seq;
2242 l2cap_send_sframe(chan, &control);
2243 } else {
2244 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2245 l2cap_ertm_send(chan);
2246 /* If any i-frames were sent, they included an ack */
2247 if (chan->buffer_seq == chan->last_acked_seq)
2248 frames_to_ack = 0;
2249 }
2250
Mat Martineauc20f8e32012-07-10 05:47:07 -07002251 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002252 * Calculate without mul or div
2253 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002254 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002255 threshold += threshold << 1;
2256 threshold >>= 2;
2257
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002258 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002259 threshold);
2260
2261 if (frames_to_ack >= threshold) {
2262 __clear_ack_timer(chan);
2263 control.super = L2CAP_SUPER_RR;
2264 control.reqseq = chan->buffer_seq;
2265 l2cap_send_sframe(chan, &control);
2266 frames_to_ack = 0;
2267 }
2268
2269 if (frames_to_ack)
2270 __set_ack_timer(chan);
2271 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002272}
2273
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002274static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2275 struct msghdr *msg, int len,
2276 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002277{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002278 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002279 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002280 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002281
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002282 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002283 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002284
2285 sent += count;
2286 len -= count;
2287
2288 /* Continuation fragments (no L2CAP header) */
2289 frag = &skb_shinfo(skb)->frag_list;
2290 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002291 struct sk_buff *tmp;
2292
Linus Torvalds1da177e2005-04-16 15:20:36 -07002293 count = min_t(unsigned int, conn->mtu, len);
2294
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002295 tmp = chan->ops->alloc_skb(chan, count,
2296 msg->msg_flags & MSG_DONTWAIT);
2297 if (IS_ERR(tmp))
2298 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002299
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002300 *frag = tmp;
2301
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002302 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2303 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002304
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002305 (*frag)->priority = skb->priority;
2306
Linus Torvalds1da177e2005-04-16 15:20:36 -07002307 sent += count;
2308 len -= count;
2309
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002310 skb->len += (*frag)->len;
2311 skb->data_len += (*frag)->len;
2312
Linus Torvalds1da177e2005-04-16 15:20:36 -07002313 frag = &(*frag)->next;
2314 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002315
2316 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002317}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002318
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002319static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002320 struct msghdr *msg, size_t len,
2321 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002322{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002323 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002324 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002325 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002326 struct l2cap_hdr *lh;
2327
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002328 BT_DBG("chan %p psm 0x%2.2x len %zu priority %u", chan,
2329 __le16_to_cpu(chan->psm), len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002330
2331 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002332
2333 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002334 msg->msg_flags & MSG_DONTWAIT);
2335 if (IS_ERR(skb))
2336 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002337
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002338 skb->priority = priority;
2339
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002340 /* 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);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002343 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002344 put_unaligned(chan->psm, (__le16 *) skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002345
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002346 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002347 if (unlikely(err < 0)) {
2348 kfree_skb(skb);
2349 return ERR_PTR(err);
2350 }
2351 return skb;
2352}
2353
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002354static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002355 struct msghdr *msg, size_t len,
2356 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002357{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002358 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002359 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002360 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002361 struct l2cap_hdr *lh;
2362
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002363 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002364
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002365 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002366
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002367 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002368 msg->msg_flags & MSG_DONTWAIT);
2369 if (IS_ERR(skb))
2370 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002371
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002372 skb->priority = priority;
2373
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002374 /* Create L2CAP header */
2375 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002376 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002377 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002378
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002379 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002380 if (unlikely(err < 0)) {
2381 kfree_skb(skb);
2382 return ERR_PTR(err);
2383 }
2384 return skb;
2385}
2386
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002387static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002388 struct msghdr *msg, size_t len,
2389 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002390{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002391 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002392 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002393 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002394 struct l2cap_hdr *lh;
2395
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002396 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002397
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002398 if (!conn)
2399 return ERR_PTR(-ENOTCONN);
2400
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002401 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002402
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002403 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002404 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002405
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002406 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002407 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002408
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002409 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002410
2411 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002412 msg->msg_flags & MSG_DONTWAIT);
2413 if (IS_ERR(skb))
2414 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002415
2416 /* Create L2CAP header */
2417 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002418 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002419 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002420
Mat Martineau18a48e72012-05-17 20:53:34 -07002421 /* Control header is populated later */
2422 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2423 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2424 else
2425 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002426
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002427 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002428 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002429
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002430 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002431 if (unlikely(err < 0)) {
2432 kfree_skb(skb);
2433 return ERR_PTR(err);
2434 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002435
Mat Martineau18a48e72012-05-17 20:53:34 -07002436 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002437 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002438 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002439}
2440
Mat Martineau94122bb2012-05-02 09:42:02 -07002441static int l2cap_segment_sdu(struct l2cap_chan *chan,
2442 struct sk_buff_head *seg_queue,
2443 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002444{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002445 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002446 u16 sdu_len;
2447 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002448 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002449
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002450 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002451
Mat Martineau94122bb2012-05-02 09:42:02 -07002452 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2453 * so fragmented skbs are not used. The HCI layer's handling
2454 * of fragmented skbs is not compatible with ERTM's queueing.
2455 */
2456
2457 /* PDU size is derived from the HCI MTU */
2458 pdu_len = chan->conn->mtu;
2459
Mat Martineaua5495742012-10-23 15:24:21 -07002460 /* Constrain PDU size for BR/EDR connections */
2461 if (!chan->hs_hcon)
2462 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002463
2464 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002465 if (chan->fcs)
2466 pdu_len -= L2CAP_FCS_SIZE;
2467
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002468 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002469
2470 /* Remote device may have requested smaller PDUs */
2471 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2472
2473 if (len <= pdu_len) {
2474 sar = L2CAP_SAR_UNSEGMENTED;
2475 sdu_len = 0;
2476 pdu_len = len;
2477 } else {
2478 sar = L2CAP_SAR_START;
2479 sdu_len = len;
2480 pdu_len -= L2CAP_SDULEN_SIZE;
2481 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002482
2483 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002484 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002485
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002486 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002487 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002488 return PTR_ERR(skb);
2489 }
2490
Mat Martineau94122bb2012-05-02 09:42:02 -07002491 bt_cb(skb)->control.sar = sar;
2492 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002493
Mat Martineau94122bb2012-05-02 09:42:02 -07002494 len -= pdu_len;
2495 if (sdu_len) {
2496 sdu_len = 0;
2497 pdu_len += L2CAP_SDULEN_SIZE;
2498 }
2499
2500 if (len <= pdu_len) {
2501 sar = L2CAP_SAR_END;
2502 pdu_len = len;
2503 } else {
2504 sar = L2CAP_SAR_CONTINUE;
2505 }
2506 }
2507
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002508 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002509}
2510
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002511int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002512 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002513{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002514 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002515 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002516 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002517
Seung-Woo Kim31e8ce82013-11-05 18:46:33 +09002518 if (!chan->conn)
2519 return -ENOTCONN;
2520
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002521 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002522 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002523 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002524 if (IS_ERR(skb))
2525 return PTR_ERR(skb);
2526
2527 l2cap_do_send(chan, skb);
2528 return len;
2529 }
2530
2531 switch (chan->mode) {
2532 case L2CAP_MODE_BASIC:
2533 /* Check outgoing MTU */
2534 if (len > chan->omtu)
2535 return -EMSGSIZE;
2536
2537 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002538 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002539 if (IS_ERR(skb))
2540 return PTR_ERR(skb);
2541
2542 l2cap_do_send(chan, skb);
2543 err = len;
2544 break;
2545
2546 case L2CAP_MODE_ERTM:
2547 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002548 /* Check outgoing MTU */
2549 if (len > chan->omtu) {
2550 err = -EMSGSIZE;
2551 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002552 }
2553
Mat Martineau94122bb2012-05-02 09:42:02 -07002554 __skb_queue_head_init(&seg_queue);
2555
2556 /* Do segmentation before calling in to the state machine,
2557 * since it's possible to block while waiting for memory
2558 * allocation.
2559 */
2560 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2561
2562 /* The channel could have been closed while segmenting,
2563 * check that it is still connected.
2564 */
2565 if (chan->state != BT_CONNECTED) {
2566 __skb_queue_purge(&seg_queue);
2567 err = -ENOTCONN;
2568 }
2569
2570 if (err)
2571 break;
2572
Mat Martineau37339372012-05-17 20:53:33 -07002573 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002574 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002575 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002576 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002577
Gustavo Padovand6603662012-05-21 13:58:22 -03002578 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002579
Mat Martineau94122bb2012-05-02 09:42:02 -07002580 /* If the skbs were not queued for sending, they'll still be in
2581 * seg_queue and need to be purged.
2582 */
2583 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002584 break;
2585
2586 default:
2587 BT_DBG("bad state %1.1x", chan->mode);
2588 err = -EBADFD;
2589 }
2590
2591 return err;
2592}
2593
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002594static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2595{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002596 struct l2cap_ctrl control;
2597 u16 seq;
2598
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002599 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002600
2601 memset(&control, 0, sizeof(control));
2602 control.sframe = 1;
2603 control.super = L2CAP_SUPER_SREJ;
2604
2605 for (seq = chan->expected_tx_seq; seq != txseq;
2606 seq = __next_seq(chan, seq)) {
2607 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2608 control.reqseq = seq;
2609 l2cap_send_sframe(chan, &control);
2610 l2cap_seq_list_append(&chan->srej_list, seq);
2611 }
2612 }
2613
2614 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002615}
2616
2617static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2618{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002619 struct l2cap_ctrl control;
2620
2621 BT_DBG("chan %p", chan);
2622
2623 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2624 return;
2625
2626 memset(&control, 0, sizeof(control));
2627 control.sframe = 1;
2628 control.super = L2CAP_SUPER_SREJ;
2629 control.reqseq = chan->srej_list.tail;
2630 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002631}
2632
2633static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2634{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002635 struct l2cap_ctrl control;
2636 u16 initial_head;
2637 u16 seq;
2638
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002639 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002640
2641 memset(&control, 0, sizeof(control));
2642 control.sframe = 1;
2643 control.super = L2CAP_SUPER_SREJ;
2644
2645 /* Capture initial list head to allow only one pass through the list. */
2646 initial_head = chan->srej_list.head;
2647
2648 do {
2649 seq = l2cap_seq_list_pop(&chan->srej_list);
2650 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2651 break;
2652
2653 control.reqseq = seq;
2654 l2cap_send_sframe(chan, &control);
2655 l2cap_seq_list_append(&chan->srej_list, seq);
2656 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002657}
2658
Mat Martineau608bcc62012-05-17 20:53:32 -07002659static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2660{
2661 struct sk_buff *acked_skb;
2662 u16 ackseq;
2663
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002664 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002665
2666 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2667 return;
2668
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002669 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002670 chan->expected_ack_seq, chan->unacked_frames);
2671
2672 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2673 ackseq = __next_seq(chan, ackseq)) {
2674
2675 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2676 if (acked_skb) {
2677 skb_unlink(acked_skb, &chan->tx_q);
2678 kfree_skb(acked_skb);
2679 chan->unacked_frames--;
2680 }
2681 }
2682
2683 chan->expected_ack_seq = reqseq;
2684
2685 if (chan->unacked_frames == 0)
2686 __clear_retrans_timer(chan);
2687
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002688 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002689}
2690
2691static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2692{
2693 BT_DBG("chan %p", chan);
2694
2695 chan->expected_tx_seq = chan->buffer_seq;
2696 l2cap_seq_list_clear(&chan->srej_list);
2697 skb_queue_purge(&chan->srej_q);
2698 chan->rx_state = L2CAP_RX_STATE_RECV;
2699}
2700
Gustavo Padovand6603662012-05-21 13:58:22 -03002701static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2702 struct l2cap_ctrl *control,
2703 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002704{
Mat Martineau608bcc62012-05-17 20:53:32 -07002705 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2706 event);
2707
2708 switch (event) {
2709 case L2CAP_EV_DATA_REQUEST:
2710 if (chan->tx_send_head == NULL)
2711 chan->tx_send_head = skb_peek(skbs);
2712
2713 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2714 l2cap_ertm_send(chan);
2715 break;
2716 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2717 BT_DBG("Enter LOCAL_BUSY");
2718 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2719
2720 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2721 /* The SREJ_SENT state must be aborted if we are to
2722 * enter the LOCAL_BUSY state.
2723 */
2724 l2cap_abort_rx_srej_sent(chan);
2725 }
2726
2727 l2cap_send_ack(chan);
2728
2729 break;
2730 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2731 BT_DBG("Exit LOCAL_BUSY");
2732 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2733
2734 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2735 struct l2cap_ctrl local_control;
2736
2737 memset(&local_control, 0, sizeof(local_control));
2738 local_control.sframe = 1;
2739 local_control.super = L2CAP_SUPER_RR;
2740 local_control.poll = 1;
2741 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002742 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002743
2744 chan->retry_count = 1;
2745 __set_monitor_timer(chan);
2746 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2747 }
2748 break;
2749 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2750 l2cap_process_reqseq(chan, control->reqseq);
2751 break;
2752 case L2CAP_EV_EXPLICIT_POLL:
2753 l2cap_send_rr_or_rnr(chan, 1);
2754 chan->retry_count = 1;
2755 __set_monitor_timer(chan);
2756 __clear_ack_timer(chan);
2757 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2758 break;
2759 case L2CAP_EV_RETRANS_TO:
2760 l2cap_send_rr_or_rnr(chan, 1);
2761 chan->retry_count = 1;
2762 __set_monitor_timer(chan);
2763 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2764 break;
2765 case L2CAP_EV_RECV_FBIT:
2766 /* Nothing to process */
2767 break;
2768 default:
2769 break;
2770 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002771}
2772
Gustavo Padovand6603662012-05-21 13:58:22 -03002773static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2774 struct l2cap_ctrl *control,
2775 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002776{
Mat Martineau608bcc62012-05-17 20:53:32 -07002777 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2778 event);
2779
2780 switch (event) {
2781 case L2CAP_EV_DATA_REQUEST:
2782 if (chan->tx_send_head == NULL)
2783 chan->tx_send_head = skb_peek(skbs);
2784 /* Queue data, but don't send. */
2785 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2786 break;
2787 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2788 BT_DBG("Enter LOCAL_BUSY");
2789 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2790
2791 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2792 /* The SREJ_SENT state must be aborted if we are to
2793 * enter the LOCAL_BUSY state.
2794 */
2795 l2cap_abort_rx_srej_sent(chan);
2796 }
2797
2798 l2cap_send_ack(chan);
2799
2800 break;
2801 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2802 BT_DBG("Exit LOCAL_BUSY");
2803 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2804
2805 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2806 struct l2cap_ctrl local_control;
2807 memset(&local_control, 0, sizeof(local_control));
2808 local_control.sframe = 1;
2809 local_control.super = L2CAP_SUPER_RR;
2810 local_control.poll = 1;
2811 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002812 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002813
2814 chan->retry_count = 1;
2815 __set_monitor_timer(chan);
2816 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2817 }
2818 break;
2819 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2820 l2cap_process_reqseq(chan, control->reqseq);
2821
2822 /* Fall through */
2823
2824 case L2CAP_EV_RECV_FBIT:
2825 if (control && control->final) {
2826 __clear_monitor_timer(chan);
2827 if (chan->unacked_frames > 0)
2828 __set_retrans_timer(chan);
2829 chan->retry_count = 0;
2830 chan->tx_state = L2CAP_TX_STATE_XMIT;
2831 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2832 }
2833 break;
2834 case L2CAP_EV_EXPLICIT_POLL:
2835 /* Ignore */
2836 break;
2837 case L2CAP_EV_MONITOR_TO:
2838 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2839 l2cap_send_rr_or_rnr(chan, 1);
2840 __set_monitor_timer(chan);
2841 chan->retry_count++;
2842 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002843 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002844 }
2845 break;
2846 default:
2847 break;
2848 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002849}
2850
Gustavo Padovand6603662012-05-21 13:58:22 -03002851static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2852 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002853{
Mat Martineau608bcc62012-05-17 20:53:32 -07002854 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2855 chan, control, skbs, event, chan->tx_state);
2856
2857 switch (chan->tx_state) {
2858 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002859 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002860 break;
2861 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002862 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002863 break;
2864 default:
2865 /* Ignore event */
2866 break;
2867 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002868}
2869
Mat Martineau4b51dae92012-05-17 20:53:37 -07002870static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2871 struct l2cap_ctrl *control)
2872{
2873 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002874 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002875}
2876
Mat Martineauf80842a2012-05-17 20:53:46 -07002877static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2878 struct l2cap_ctrl *control)
2879{
2880 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002881 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002882}
2883
Linus Torvalds1da177e2005-04-16 15:20:36 -07002884/* Copy frame to all raw sockets on that connection */
2885static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2886{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002887 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002888 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002889
2890 BT_DBG("conn %p", conn);
2891
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002892 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002893
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002894 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002895 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002896 continue;
2897
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02002898 /* Don't send frame to the channel it came from */
2899 if (bt_cb(skb)->chan == chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002900 continue;
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02002901
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002902 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002903 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002904 continue;
Gustavo Padovan80b98022012-05-27 22:27:51 -03002905 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002906 kfree_skb(nskb);
2907 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002908
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002909 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002910}
2911
2912/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002913static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2914 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002915{
2916 struct sk_buff *skb, **frag;
2917 struct l2cap_cmd_hdr *cmd;
2918 struct l2cap_hdr *lh;
2919 int len, count;
2920
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002921 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2922 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002923
Anderson Lizardo300b9622013-06-02 16:30:40 -04002924 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2925 return NULL;
2926
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2928 count = min_t(unsigned int, conn->mtu, len);
2929
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002930 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002931 if (!skb)
2932 return NULL;
2933
2934 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002935 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002936
2937 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002938 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002939 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002940 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002941
2942 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2943 cmd->code = code;
2944 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002945 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002946
2947 if (dlen) {
2948 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2949 memcpy(skb_put(skb, count), data, count);
2950 data += count;
2951 }
2952
2953 len -= skb->len;
2954
2955 /* Continuation fragments (no L2CAP header) */
2956 frag = &skb_shinfo(skb)->frag_list;
2957 while (len) {
2958 count = min_t(unsigned int, conn->mtu, len);
2959
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002960 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002961 if (!*frag)
2962 goto fail;
2963
2964 memcpy(skb_put(*frag, count), data, count);
2965
2966 len -= count;
2967 data += count;
2968
2969 frag = &(*frag)->next;
2970 }
2971
2972 return skb;
2973
2974fail:
2975 kfree_skb(skb);
2976 return NULL;
2977}
2978
Gustavo Padovan2d792812012-10-06 10:07:01 +01002979static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2980 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002981{
2982 struct l2cap_conf_opt *opt = *ptr;
2983 int len;
2984
2985 len = L2CAP_CONF_OPT_SIZE + opt->len;
2986 *ptr += len;
2987
2988 *type = opt->type;
2989 *olen = opt->len;
2990
2991 switch (opt->len) {
2992 case 1:
2993 *val = *((u8 *) opt->val);
2994 break;
2995
2996 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002997 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002998 break;
2999
3000 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04003001 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003002 break;
3003
3004 default:
3005 *val = (unsigned long) opt->val;
3006 break;
3007 }
3008
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003009 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003010 return len;
3011}
3012
Linus Torvalds1da177e2005-04-16 15:20:36 -07003013static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
3014{
3015 struct l2cap_conf_opt *opt = *ptr;
3016
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003017 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003018
3019 opt->type = type;
3020 opt->len = len;
3021
3022 switch (len) {
3023 case 1:
3024 *((u8 *) opt->val) = val;
3025 break;
3026
3027 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003028 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003029 break;
3030
3031 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003032 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003033 break;
3034
3035 default:
3036 memcpy(opt->val, (void *) val, len);
3037 break;
3038 }
3039
3040 *ptr += L2CAP_CONF_OPT_SIZE + len;
3041}
3042
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003043static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
3044{
3045 struct l2cap_conf_efs efs;
3046
Szymon Janc1ec918c2011-11-16 09:32:21 +01003047 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003048 case L2CAP_MODE_ERTM:
3049 efs.id = chan->local_id;
3050 efs.stype = chan->local_stype;
3051 efs.msdu = cpu_to_le16(chan->local_msdu);
3052 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003053 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003054 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003055 break;
3056
3057 case L2CAP_MODE_STREAMING:
3058 efs.id = 1;
3059 efs.stype = L2CAP_SERV_BESTEFFORT;
3060 efs.msdu = cpu_to_le16(chan->local_msdu);
3061 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
3062 efs.acc_lat = 0;
3063 efs.flush_to = 0;
3064 break;
3065
3066 default:
3067 return;
3068 }
3069
3070 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003071 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003072}
3073
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003074static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003075{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003076 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003077 ack_timer.work);
3078 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003079
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003080 BT_DBG("chan %p", chan);
3081
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003082 l2cap_chan_lock(chan);
3083
Mat Martineau03625202012-05-17 20:53:51 -07003084 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3085 chan->last_acked_seq);
3086
3087 if (frames_to_ack)
3088 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003089
3090 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003091 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003092}
3093
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003094int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003095{
Mat Martineau3c588192012-04-11 10:48:42 -07003096 int err;
3097
Mat Martineau105bdf92012-04-27 16:50:48 -07003098 chan->next_tx_seq = 0;
3099 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003100 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003101 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003102 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003103 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003104 chan->last_acked_seq = 0;
3105 chan->sdu = NULL;
3106 chan->sdu_last_frag = NULL;
3107 chan->sdu_len = 0;
3108
Mat Martineaud34c34f2012-05-14 14:49:27 -07003109 skb_queue_head_init(&chan->tx_q);
3110
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003111 chan->local_amp_id = AMP_ID_BREDR;
3112 chan->move_id = AMP_ID_BREDR;
Mat Martineau08333282012-10-23 15:24:06 -07003113 chan->move_state = L2CAP_MOVE_STABLE;
3114 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3115
Mat Martineau105bdf92012-04-27 16:50:48 -07003116 if (chan->mode != L2CAP_MODE_ERTM)
3117 return 0;
3118
3119 chan->rx_state = L2CAP_RX_STATE_RECV;
3120 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003121
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003122 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3123 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3124 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003125
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003126 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003127
Mat Martineau3c588192012-04-11 10:48:42 -07003128 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3129 if (err < 0)
3130 return err;
3131
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003132 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3133 if (err < 0)
3134 l2cap_seq_list_free(&chan->srej_list);
3135
3136 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003137}
3138
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003139static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3140{
3141 switch (mode) {
3142 case L2CAP_MODE_STREAMING:
3143 case L2CAP_MODE_ERTM:
3144 if (l2cap_mode_supported(mode, remote_feat_mask))
3145 return mode;
3146 /* fall through */
3147 default:
3148 return L2CAP_MODE_BASIC;
3149 }
3150}
3151
Marcel Holtmann848566b2013-10-01 22:59:22 -07003152static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003153{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003154 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003155}
3156
Marcel Holtmann848566b2013-10-01 22:59:22 -07003157static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003158{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003159 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003160}
3161
Mat Martineau36c86c82012-10-23 15:24:20 -07003162static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3163 struct l2cap_conf_rfc *rfc)
3164{
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003165 if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) {
Mat Martineau36c86c82012-10-23 15:24:20 -07003166 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3167
3168 /* Class 1 devices have must have ERTM timeouts
3169 * exceeding the Link Supervision Timeout. The
3170 * default Link Supervision Timeout for AMP
3171 * controllers is 10 seconds.
3172 *
3173 * Class 1 devices use 0xffffffff for their
3174 * best-effort flush timeout, so the clamping logic
3175 * will result in a timeout that meets the above
3176 * requirement. ERTM timeouts are 16-bit values, so
3177 * the maximum timeout is 65.535 seconds.
3178 */
3179
3180 /* Convert timeout to milliseconds and round */
3181 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3182
3183 /* This is the recommended formula for class 2 devices
3184 * that start ERTM timers when packets are sent to the
3185 * controller.
3186 */
3187 ertm_to = 3 * ertm_to + 500;
3188
3189 if (ertm_to > 0xffff)
3190 ertm_to = 0xffff;
3191
3192 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3193 rfc->monitor_timeout = rfc->retrans_timeout;
3194 } else {
3195 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3196 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3197 }
3198}
3199
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003200static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3201{
3202 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Marcel Holtmann848566b2013-10-01 22:59:22 -07003203 __l2cap_ews_supported(chan->conn)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003204 /* use extended control field */
3205 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003206 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3207 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003208 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003209 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003210 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3211 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003212 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003213}
3214
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003215static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003216{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003217 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003218 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003219 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003220 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003221
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003222 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003223
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003224 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003225 goto done;
3226
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003227 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003228 case L2CAP_MODE_STREAMING:
3229 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003230 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003231 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003232
Marcel Holtmann848566b2013-10-01 22:59:22 -07003233 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003234 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3235
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003236 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003237 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003238 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003239 break;
3240 }
3241
3242done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003243 if (chan->imtu != L2CAP_DEFAULT_MTU)
3244 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003245
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003246 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003247 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003248 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003249 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003250 break;
3251
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003252 rfc.mode = L2CAP_MODE_BASIC;
3253 rfc.txwin_size = 0;
3254 rfc.max_transmit = 0;
3255 rfc.retrans_timeout = 0;
3256 rfc.monitor_timeout = 0;
3257 rfc.max_pdu_size = 0;
3258
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003259 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003260 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003261 break;
3262
3263 case L2CAP_MODE_ERTM:
3264 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003265 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003266
3267 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003268
3269 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003270 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3271 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003272 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003273
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003274 l2cap_txwin_setup(chan);
3275
3276 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003277 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003278
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003279 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003280 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003281
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003282 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3283 l2cap_add_opt_efs(&ptr, chan);
3284
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003285 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3286 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003287 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003288
3289 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3290 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003291 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003292 chan->fcs = L2CAP_FCS_NONE;
3293 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3294 chan->fcs);
3295 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003296 break;
3297
3298 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003299 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003300 rfc.mode = L2CAP_MODE_STREAMING;
3301 rfc.txwin_size = 0;
3302 rfc.max_transmit = 0;
3303 rfc.retrans_timeout = 0;
3304 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003305
3306 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003307 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3308 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003309 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003310
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003311 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003312 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003313
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003314 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3315 l2cap_add_opt_efs(&ptr, chan);
3316
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003317 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3318 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003319 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003320 chan->fcs = L2CAP_FCS_NONE;
3321 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3322 chan->fcs);
3323 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003324 break;
3325 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003326
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003327 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003328 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003329
3330 return ptr - data;
3331}
3332
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003333static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003334{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003335 struct l2cap_conf_rsp *rsp = data;
3336 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003337 void *req = chan->conf_req;
3338 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003339 int type, hint, olen;
3340 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003341 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003342 struct l2cap_conf_efs efs;
3343 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003344 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003345 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003346 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003347
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003348 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003349
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003350 while (len >= L2CAP_CONF_OPT_SIZE) {
3351 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003352
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003353 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003354 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003355
3356 switch (type) {
3357 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003358 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003359 break;
3360
3361 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003362 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003363 break;
3364
3365 case L2CAP_CONF_QOS:
3366 break;
3367
Marcel Holtmann6464f352007-10-20 13:39:51 +02003368 case L2CAP_CONF_RFC:
3369 if (olen == sizeof(rfc))
3370 memcpy(&rfc, (void *) val, olen);
3371 break;
3372
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003373 case L2CAP_CONF_FCS:
3374 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003375 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003376 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003377
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003378 case L2CAP_CONF_EFS:
3379 remote_efs = 1;
3380 if (olen == sizeof(efs))
3381 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003382 break;
3383
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003384 case L2CAP_CONF_EWS:
Marcel Holtmann848566b2013-10-01 22:59:22 -07003385 if (!chan->conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003386 return -ECONNREFUSED;
3387
3388 set_bit(FLAG_EXT_CTRL, &chan->flags);
3389 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003390 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003391 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003392 break;
3393
3394 default:
3395 if (hint)
3396 break;
3397
3398 result = L2CAP_CONF_UNKNOWN;
3399 *((u8 *) ptr++) = type;
3400 break;
3401 }
3402 }
3403
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003404 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003405 goto done;
3406
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003407 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003408 case L2CAP_MODE_STREAMING:
3409 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003410 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003411 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003412 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003413 break;
3414 }
3415
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003416 if (remote_efs) {
Marcel Holtmann848566b2013-10-01 22:59:22 -07003417 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003418 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3419 else
3420 return -ECONNREFUSED;
3421 }
3422
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003423 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003424 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003425
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003426 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003427 }
3428
3429done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003430 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003431 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003432 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003433
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003434 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003435 return -ECONNREFUSED;
3436
Gustavo Padovan2d792812012-10-06 10:07:01 +01003437 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3438 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003439 }
3440
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003441 if (result == L2CAP_CONF_SUCCESS) {
3442 /* Configure output options and let the other side know
3443 * which ones we don't like. */
3444
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003445 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3446 result = L2CAP_CONF_UNACCEPT;
3447 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003448 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003449 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003450 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003451 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003452
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003453 if (remote_efs) {
3454 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003455 efs.stype != L2CAP_SERV_NOTRAFIC &&
3456 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003457
3458 result = L2CAP_CONF_UNACCEPT;
3459
3460 if (chan->num_conf_req >= 1)
3461 return -ECONNREFUSED;
3462
3463 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003464 sizeof(efs),
3465 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003466 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003467 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003468 result = L2CAP_CONF_PENDING;
3469 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003470 }
3471 }
3472
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003473 switch (rfc.mode) {
3474 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003475 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003476 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003477 break;
3478
3479 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003480 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3481 chan->remote_tx_win = rfc.txwin_size;
3482 else
3483 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3484
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003485 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003486
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003487 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003488 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3489 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003490 rfc.max_pdu_size = cpu_to_le16(size);
3491 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003492
Mat Martineau36c86c82012-10-23 15:24:20 -07003493 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003494
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003495 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003496
3497 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003498 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003499
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003500 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3501 chan->remote_id = efs.id;
3502 chan->remote_stype = efs.stype;
3503 chan->remote_msdu = le16_to_cpu(efs.msdu);
3504 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003505 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003506 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003507 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003508 chan->remote_sdu_itime =
3509 le32_to_cpu(efs.sdu_itime);
3510 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003511 sizeof(efs),
3512 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003513 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003514 break;
3515
3516 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003517 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003518 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3519 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003520 rfc.max_pdu_size = cpu_to_le16(size);
3521 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003522
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003523 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003524
Gustavo Padovan2d792812012-10-06 10:07:01 +01003525 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3526 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003527
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003528 break;
3529
3530 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003531 result = L2CAP_CONF_UNACCEPT;
3532
3533 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003534 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003535 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003536
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003537 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003538 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003539 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003540 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003541 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003542 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003543
3544 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003545}
3546
Gustavo Padovan2d792812012-10-06 10:07:01 +01003547static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3548 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003549{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003550 struct l2cap_conf_req *req = data;
3551 void *ptr = req->data;
3552 int type, olen;
3553 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003554 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003555 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003556
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003557 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003558
3559 while (len >= L2CAP_CONF_OPT_SIZE) {
3560 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3561
3562 switch (type) {
3563 case L2CAP_CONF_MTU:
3564 if (val < L2CAP_DEFAULT_MIN_MTU) {
3565 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003566 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003567 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003568 chan->imtu = val;
3569 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003570 break;
3571
3572 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003573 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003574 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003575 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003576 break;
3577
3578 case L2CAP_CONF_RFC:
3579 if (olen == sizeof(rfc))
3580 memcpy(&rfc, (void *)val, olen);
3581
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003582 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003583 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003584 return -ECONNREFUSED;
3585
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003586 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003587
3588 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003589 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003590 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003591
3592 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003593 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003594 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003595 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003596 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003597
3598 case L2CAP_CONF_EFS:
3599 if (olen == sizeof(efs))
3600 memcpy(&efs, (void *)val, olen);
3601
3602 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003603 efs.stype != L2CAP_SERV_NOTRAFIC &&
3604 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003605 return -ECONNREFUSED;
3606
Gustavo Padovan2d792812012-10-06 10:07:01 +01003607 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3608 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003609 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003610
3611 case L2CAP_CONF_FCS:
3612 if (*result == L2CAP_CONF_PENDING)
3613 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003614 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003615 &chan->conf_state);
3616 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003617 }
3618 }
3619
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003620 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003621 return -ECONNREFUSED;
3622
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003623 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003624
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003625 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003626 switch (rfc.mode) {
3627 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003628 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3629 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3630 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003631 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3632 chan->ack_win = min_t(u16, chan->ack_win,
3633 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003634
3635 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3636 chan->local_msdu = le16_to_cpu(efs.msdu);
3637 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003638 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003639 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3640 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003641 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003642 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003643 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003644
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003645 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003646 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003647 }
3648 }
3649
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003650 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003651 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003652
3653 return ptr - data;
3654}
3655
Gustavo Padovan2d792812012-10-06 10:07:01 +01003656static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3657 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003658{
3659 struct l2cap_conf_rsp *rsp = data;
3660 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003661
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003662 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003663
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003664 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003665 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003666 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003667
3668 return ptr - data;
3669}
3670
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03003671void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan)
3672{
3673 struct l2cap_le_conn_rsp rsp;
3674 struct l2cap_conn *conn = chan->conn;
3675
3676 BT_DBG("chan %p", chan);
3677
3678 rsp.dcid = cpu_to_le16(chan->scid);
3679 rsp.mtu = cpu_to_le16(chan->imtu);
3680 rsp.mps = __constant_cpu_to_le16(L2CAP_LE_DEFAULT_MPS);
3681 rsp.credits = __constant_cpu_to_le16(L2CAP_LE_MAX_CREDITS);
3682 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3683
3684 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
3685 &rsp);
3686}
3687
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003688void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003689{
3690 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003691 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003692 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003693 u8 rsp_code;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003694
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003695 rsp.scid = cpu_to_le16(chan->dcid);
3696 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003697 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3698 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003699
3700 if (chan->hs_hcon)
3701 rsp_code = L2CAP_CREATE_CHAN_RSP;
3702 else
3703 rsp_code = L2CAP_CONN_RSP;
3704
3705 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3706
3707 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003708
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003709 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003710 return;
3711
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003712 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003713 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003714 chan->num_conf_req++;
3715}
3716
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003717static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003718{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003719 int type, olen;
3720 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003721 /* Use sane default values in case a misbehaving remote device
3722 * did not send an RFC or extended window size option.
3723 */
3724 u16 txwin_ext = chan->ack_win;
3725 struct l2cap_conf_rfc rfc = {
3726 .mode = chan->mode,
3727 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3728 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3729 .max_pdu_size = cpu_to_le16(chan->imtu),
3730 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3731 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003732
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003733 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003734
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003735 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003736 return;
3737
3738 while (len >= L2CAP_CONF_OPT_SIZE) {
3739 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3740
Mat Martineauc20f8e32012-07-10 05:47:07 -07003741 switch (type) {
3742 case L2CAP_CONF_RFC:
3743 if (olen == sizeof(rfc))
3744 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003745 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003746 case L2CAP_CONF_EWS:
3747 txwin_ext = val;
3748 break;
3749 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003750 }
3751
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003752 switch (rfc.mode) {
3753 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003754 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3755 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003756 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3757 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3758 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3759 else
3760 chan->ack_win = min_t(u16, chan->ack_win,
3761 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003762 break;
3763 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003764 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003765 }
3766}
3767
Gustavo Padovan2d792812012-10-06 10:07:01 +01003768static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003769 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3770 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003771{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003772 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003773
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003774 if (cmd_len < sizeof(*rej))
3775 return -EPROTO;
3776
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003777 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003778 return 0;
3779
3780 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003781 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003782 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003783
3784 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003785 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003786
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003787 l2cap_conn_start(conn);
3788 }
3789
3790 return 0;
3791}
3792
Mat Martineau17009152012-10-23 15:24:07 -07003793static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3794 struct l2cap_cmd_hdr *cmd,
3795 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003796{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003797 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3798 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003799 struct l2cap_chan *chan = NULL, *pchan;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003800 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003801
3802 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003803 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003804
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003805 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003806
3807 /* Check if we have socket listening on psm */
Marcel Holtmann6f59b902013-10-13 05:24:01 -07003808 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03003809 &conn->hcon->dst, ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003810 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003811 result = L2CAP_CR_BAD_PSM;
3812 goto sendresp;
3813 }
3814
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003815 mutex_lock(&conn->chan_lock);
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02003816 l2cap_chan_lock(pchan);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003817
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003818 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003819 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003820 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003821 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003822 result = L2CAP_CR_SEC_BLOCK;
3823 goto response;
3824 }
3825
Linus Torvalds1da177e2005-04-16 15:20:36 -07003826 result = L2CAP_CR_NO_MEM;
3827
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003828 /* Check if we already have channel with that dcid */
3829 if (__l2cap_get_chan_by_dcid(conn, scid))
3830 goto response;
3831
Gustavo Padovan80b98022012-05-27 22:27:51 -03003832 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003833 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003834 goto response;
3835
Syam Sidhardhan330b6c12013-08-06 01:59:12 +09003836 /* For certain devices (ex: HID mouse), support for authentication,
3837 * pairing and bonding is optional. For such devices, inorder to avoid
3838 * the ACL alive for too long after L2CAP disconnection, reset the ACL
3839 * disc_timeout back to HCI_DISCONN_TIMEOUT during L2CAP connect.
3840 */
3841 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
3842
Marcel Holtmann7eafc592013-10-13 08:12:47 -07003843 bacpy(&chan->src, &conn->hcon->src);
3844 bacpy(&chan->dst, &conn->hcon->dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07003845 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
3846 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003847 chan->psm = psm;
3848 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003849 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003850
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003851 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003852
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003853 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003854
Gustavo Padovan8d836d72013-10-15 19:24:47 -03003855 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003856
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003857 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003858
Marcel Holtmann984947d2009-02-06 23:35:19 +01003859 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003860 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07003861 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003862 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003863 result = L2CAP_CR_PEND;
3864 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003865 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003866 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003867 /* Force pending result for AMP controllers.
3868 * The connection will succeed after the
3869 * physical link is up.
3870 */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003871 if (amp_id == AMP_ID_BREDR) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003872 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau17009152012-10-23 15:24:07 -07003873 result = L2CAP_CR_SUCCESS;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003874 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003875 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003876 result = L2CAP_CR_PEND;
Mat Martineau17009152012-10-23 15:24:07 -07003877 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003878 status = L2CAP_CS_NO_INFO;
3879 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003880 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003881 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003882 result = L2CAP_CR_PEND;
3883 status = L2CAP_CS_AUTHEN_PEND;
3884 }
3885 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003886 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003887 result = L2CAP_CR_PEND;
3888 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003889 }
3890
Linus Torvalds1da177e2005-04-16 15:20:36 -07003891response:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02003892 l2cap_chan_unlock(pchan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003893 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003894
3895sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003896 rsp.scid = cpu_to_le16(scid);
3897 rsp.dcid = cpu_to_le16(dcid);
3898 rsp.result = cpu_to_le16(result);
3899 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003900 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003901
3902 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3903 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003904 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003905
3906 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3907 conn->info_ident = l2cap_get_ident(conn);
3908
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003909 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003910
Gustavo Padovan2d792812012-10-06 10:07:01 +01003911 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3912 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003913 }
3914
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003915 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003916 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003917 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003918 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003919 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003920 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003921 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003922 }
Mat Martineau17009152012-10-23 15:24:07 -07003923
3924 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003925}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003926
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003927static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003928 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003929{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303930 struct hci_dev *hdev = conn->hcon->hdev;
3931 struct hci_conn *hcon = conn->hcon;
3932
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003933 if (cmd_len < sizeof(struct l2cap_conn_req))
3934 return -EPROTO;
3935
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303936 hci_dev_lock(hdev);
3937 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3938 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3939 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3940 hcon->dst_type, 0, NULL, 0,
3941 hcon->dev_class);
3942 hci_dev_unlock(hdev);
3943
Gustavo Padovan300229f2012-10-12 19:40:40 +08003944 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003945 return 0;
3946}
3947
Mat Martineau5909cf32012-10-23 15:24:08 -07003948static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003949 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3950 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003951{
3952 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3953 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003954 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003955 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003956 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003957
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003958 if (cmd_len < sizeof(*rsp))
3959 return -EPROTO;
3960
Linus Torvalds1da177e2005-04-16 15:20:36 -07003961 scid = __le16_to_cpu(rsp->scid);
3962 dcid = __le16_to_cpu(rsp->dcid);
3963 result = __le16_to_cpu(rsp->result);
3964 status = __le16_to_cpu(rsp->status);
3965
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003966 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 +01003967 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003968
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003969 mutex_lock(&conn->chan_lock);
3970
Linus Torvalds1da177e2005-04-16 15:20:36 -07003971 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003972 chan = __l2cap_get_chan_by_scid(conn, scid);
3973 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003974 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003975 goto unlock;
3976 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003977 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003978 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3979 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003980 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003981 goto unlock;
3982 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003983 }
3984
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003985 err = 0;
3986
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003987 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003988
Linus Torvalds1da177e2005-04-16 15:20:36 -07003989 switch (result) {
3990 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03003991 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003992 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003993 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003994 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003995
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003996 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003997 break;
3998
Linus Torvalds1da177e2005-04-16 15:20:36 -07003999 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004000 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004001 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004002 break;
4003
4004 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004005 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004006 break;
4007
4008 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004009 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004010 break;
4011 }
4012
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004013 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004014
4015unlock:
4016 mutex_unlock(&conn->chan_lock);
4017
4018 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004019}
4020
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004021static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07004022{
4023 /* FCS is enabled only in ERTM or streaming mode, if one or both
4024 * sides request it.
4025 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03004026 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004027 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02004028 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004029 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07004030}
4031
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004032static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
4033 u8 ident, u16 flags)
4034{
4035 struct l2cap_conn *conn = chan->conn;
4036
4037 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
4038 flags);
4039
4040 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
4041 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
4042
4043 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
4044 l2cap_build_conf_rsp(chan, data,
4045 L2CAP_CONF_SUCCESS, flags), data);
4046}
4047
Johan Hedberg662d6522013-10-16 11:20:47 +03004048static void cmd_reject_invalid_cid(struct l2cap_conn *conn, u8 ident,
4049 u16 scid, u16 dcid)
4050{
4051 struct l2cap_cmd_rej_cid rej;
4052
4053 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
4054 rej.scid = __cpu_to_le16(scid);
4055 rej.dcid = __cpu_to_le16(dcid);
4056
4057 l2cap_send_cmd(conn, ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
4058}
4059
Gustavo Padovan2d792812012-10-06 10:07:01 +01004060static inline int l2cap_config_req(struct l2cap_conn *conn,
4061 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4062 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004063{
4064 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
4065 u16 dcid, flags;
4066 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004067 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07004068 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004069
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004070 if (cmd_len < sizeof(*req))
4071 return -EPROTO;
4072
Linus Torvalds1da177e2005-04-16 15:20:36 -07004073 dcid = __le16_to_cpu(req->dcid);
4074 flags = __le16_to_cpu(req->flags);
4075
4076 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
4077
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004078 chan = l2cap_get_chan_by_scid(conn, dcid);
Johan Hedberg662d6522013-10-16 11:20:47 +03004079 if (!chan) {
4080 cmd_reject_invalid_cid(conn, cmd->ident, dcid, 0);
4081 return 0;
4082 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004083
David S. Miller033b1142011-07-21 13:38:42 -07004084 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Johan Hedberg662d6522013-10-16 11:20:47 +03004085 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4086 chan->dcid);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004087 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004088 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004089
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004090 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07004091 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004092 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004093 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004094 l2cap_build_conf_rsp(chan, rsp,
4095 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004096 goto unlock;
4097 }
4098
4099 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004100 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4101 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004102
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004103 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004104 /* Incomplete config. Send empty response. */
4105 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004106 l2cap_build_conf_rsp(chan, rsp,
4107 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004108 goto unlock;
4109 }
4110
4111 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004112 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004113 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004114 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004115 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004116 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004117
Mat Martineau1500109b2012-10-23 15:24:15 -07004118 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004119 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004120 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004121
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004122 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004123 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004124
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004125 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004126 goto unlock;
4127
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004128 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004129 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004130
Mat Martineau105bdf92012-04-27 16:50:48 -07004131 if (chan->mode == L2CAP_MODE_ERTM ||
4132 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004133 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004134
Mat Martineau3c588192012-04-11 10:48:42 -07004135 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004136 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004137 else
4138 l2cap_chan_ready(chan);
4139
Marcel Holtmann876d9482007-10-20 13:35:42 +02004140 goto unlock;
4141 }
4142
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004143 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004144 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004145 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004146 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004147 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004148 }
4149
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004150 /* Got Conf Rsp PENDING from remote side and asume we sent
4151 Conf Rsp PENDING in the code above */
4152 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004153 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004154
4155 /* check compatibility */
4156
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004157 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004158 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004159 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4160 else
4161 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004162 }
4163
Linus Torvalds1da177e2005-04-16 15:20:36 -07004164unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004165 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004166 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004167}
4168
Gustavo Padovan2d792812012-10-06 10:07:01 +01004169static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004170 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4171 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004172{
4173 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4174 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004175 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004176 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004177 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004178
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004179 if (cmd_len < sizeof(*rsp))
4180 return -EPROTO;
4181
Linus Torvalds1da177e2005-04-16 15:20:36 -07004182 scid = __le16_to_cpu(rsp->scid);
4183 flags = __le16_to_cpu(rsp->flags);
4184 result = __le16_to_cpu(rsp->result);
4185
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004186 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4187 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004188
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004189 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004190 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004191 return 0;
4192
4193 switch (result) {
4194 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004195 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004196 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004197 break;
4198
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004199 case L2CAP_CONF_PENDING:
4200 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4201
4202 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4203 char buf[64];
4204
4205 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004206 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004207 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004208 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004209 goto done;
4210 }
4211
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004212 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004213 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4214 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004215 } else {
4216 if (l2cap_check_efs(chan)) {
4217 amp_create_logical_link(chan);
4218 chan->ident = cmd->ident;
4219 }
4220 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004221 }
4222 goto done;
4223
Linus Torvalds1da177e2005-04-16 15:20:36 -07004224 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004225 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004226 char req[64];
4227
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004228 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004229 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004230 goto done;
4231 }
4232
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004233 /* throw out any old stored conf requests */
4234 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004235 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004236 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004237 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004238 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004239 goto done;
4240 }
4241
4242 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004243 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004244 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004245 if (result != L2CAP_CONF_SUCCESS)
4246 goto done;
4247 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004248 }
4249
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004250 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004251 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004252
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004253 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004254 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004255 goto done;
4256 }
4257
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004258 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004259 goto done;
4260
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004261 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004262
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004263 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004264 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004265
Mat Martineau105bdf92012-04-27 16:50:48 -07004266 if (chan->mode == L2CAP_MODE_ERTM ||
4267 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004268 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004269
Mat Martineau3c588192012-04-11 10:48:42 -07004270 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004271 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004272 else
4273 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004274 }
4275
4276done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004277 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004278 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004279}
4280
Gustavo Padovan2d792812012-10-06 10:07:01 +01004281static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004282 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4283 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004284{
4285 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4286 struct l2cap_disconn_rsp rsp;
4287 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004288 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004289
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004290 if (cmd_len != sizeof(*req))
4291 return -EPROTO;
4292
Linus Torvalds1da177e2005-04-16 15:20:36 -07004293 scid = __le16_to_cpu(req->scid);
4294 dcid = __le16_to_cpu(req->dcid);
4295
4296 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4297
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004298 mutex_lock(&conn->chan_lock);
4299
4300 chan = __l2cap_get_chan_by_scid(conn, dcid);
4301 if (!chan) {
4302 mutex_unlock(&conn->chan_lock);
Johan Hedberg662d6522013-10-16 11:20:47 +03004303 cmd_reject_invalid_cid(conn, cmd->ident, dcid, scid);
4304 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004305 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004306
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004307 l2cap_chan_lock(chan);
4308
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004309 rsp.dcid = cpu_to_le16(chan->scid);
4310 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004311 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4312
Gustavo Padovan5ec1bbe2013-10-15 19:24:48 -03004313 chan->ops->set_shutdown(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004314
Mat Martineau61d6ef32012-04-27 16:50:50 -07004315 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004316 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004317
4318 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004319
Gustavo Padovan80b98022012-05-27 22:27:51 -03004320 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004321 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004322
4323 mutex_unlock(&conn->chan_lock);
4324
Linus Torvalds1da177e2005-04-16 15:20:36 -07004325 return 0;
4326}
4327
Gustavo Padovan2d792812012-10-06 10:07:01 +01004328static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004329 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4330 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004331{
4332 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4333 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004334 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004335
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004336 if (cmd_len != sizeof(*rsp))
4337 return -EPROTO;
4338
Linus Torvalds1da177e2005-04-16 15:20:36 -07004339 scid = __le16_to_cpu(rsp->scid);
4340 dcid = __le16_to_cpu(rsp->dcid);
4341
4342 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4343
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004344 mutex_lock(&conn->chan_lock);
4345
4346 chan = __l2cap_get_chan_by_scid(conn, scid);
4347 if (!chan) {
4348 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004349 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004350 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004351
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004352 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004353
Mat Martineau61d6ef32012-04-27 16:50:50 -07004354 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004355 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004356
4357 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004358
Gustavo Padovan80b98022012-05-27 22:27:51 -03004359 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004360 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004361
4362 mutex_unlock(&conn->chan_lock);
4363
Linus Torvalds1da177e2005-04-16 15:20:36 -07004364 return 0;
4365}
4366
Gustavo Padovan2d792812012-10-06 10:07:01 +01004367static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004368 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4369 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004370{
4371 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004372 u16 type;
4373
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004374 if (cmd_len != sizeof(*req))
4375 return -EPROTO;
4376
Linus Torvalds1da177e2005-04-16 15:20:36 -07004377 type = __le16_to_cpu(req->type);
4378
4379 BT_DBG("type 0x%4.4x", type);
4380
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004381 if (type == L2CAP_IT_FEAT_MASK) {
4382 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004383 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004384 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004385 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4386 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004387 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004388 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004389 | L2CAP_FEAT_FCS;
Marcel Holtmann848566b2013-10-01 22:59:22 -07004390 if (conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004391 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004392 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004393
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004394 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004395 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4396 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004397 } else if (type == L2CAP_IT_FIXED_CHAN) {
4398 u8 buf[12];
4399 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004400
Marcel Holtmann848566b2013-10-01 22:59:22 -07004401 if (conn->hs_enabled)
Mat Martineau50a147c2011-11-02 16:18:34 -07004402 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4403 else
4404 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4405
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004406 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4407 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004408 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004409 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4410 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004411 } else {
4412 struct l2cap_info_rsp rsp;
4413 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004414 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004415 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4416 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004417 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004418
4419 return 0;
4420}
4421
Gustavo Padovan2d792812012-10-06 10:07:01 +01004422static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004423 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4424 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004425{
4426 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4427 u16 type, result;
4428
Jaganath Kanakkassery3f6fa3d2013-06-21 19:55:11 +05304429 if (cmd_len < sizeof(*rsp))
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004430 return -EPROTO;
4431
Linus Torvalds1da177e2005-04-16 15:20:36 -07004432 type = __le16_to_cpu(rsp->type);
4433 result = __le16_to_cpu(rsp->result);
4434
4435 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4436
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004437 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4438 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004439 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004440 return 0;
4441
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004442 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004443
Ville Tervoadb08ed2010-08-04 09:43:33 +03004444 if (result != L2CAP_IR_SUCCESS) {
4445 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4446 conn->info_ident = 0;
4447
4448 l2cap_conn_start(conn);
4449
4450 return 0;
4451 }
4452
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004453 switch (type) {
4454 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004455 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004456
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004457 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004458 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004459 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004460
4461 conn->info_ident = l2cap_get_ident(conn);
4462
4463 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004464 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004465 } else {
4466 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4467 conn->info_ident = 0;
4468
4469 l2cap_conn_start(conn);
4470 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004471 break;
4472
4473 case L2CAP_IT_FIXED_CHAN:
4474 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004475 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004476 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004477
4478 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004479 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004480 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004481
Linus Torvalds1da177e2005-04-16 15:20:36 -07004482 return 0;
4483}
4484
Mat Martineau17009152012-10-23 15:24:07 -07004485static int l2cap_create_channel_req(struct l2cap_conn *conn,
4486 struct l2cap_cmd_hdr *cmd,
4487 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004488{
4489 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004490 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004491 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004492 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004493 u16 psm, scid;
4494
4495 if (cmd_len != sizeof(*req))
4496 return -EPROTO;
4497
Marcel Holtmann848566b2013-10-01 22:59:22 -07004498 if (!conn->hs_enabled)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004499 return -EINVAL;
4500
4501 psm = le16_to_cpu(req->psm);
4502 scid = le16_to_cpu(req->scid);
4503
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004504 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 -07004505
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004506 /* For controller id 0 make BR/EDR connection */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004507 if (req->amp_id == AMP_ID_BREDR) {
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004508 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4509 req->amp_id);
4510 return 0;
4511 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004512
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004513 /* Validate AMP controller id */
4514 hdev = hci_dev_get(req->amp_id);
4515 if (!hdev)
4516 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004517
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004518 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004519 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004520 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004521 }
4522
4523 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4524 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004525 if (chan) {
4526 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4527 struct hci_conn *hs_hcon;
4528
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07004529 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
4530 &conn->hcon->dst);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004531 if (!hs_hcon) {
4532 hci_dev_put(hdev);
Johan Hedberg662d6522013-10-16 11:20:47 +03004533 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4534 chan->dcid);
4535 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004536 }
4537
4538 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4539
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004540 mgr->bredr_chan = chan;
4541 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004542 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004543 conn->mtu = hdev->block_mtu;
4544 }
4545
4546 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004547
4548 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004549
4550error:
4551 rsp.dcid = 0;
4552 rsp.scid = cpu_to_le16(scid);
4553 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4554 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4555
4556 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4557 sizeof(rsp), &rsp);
4558
Johan Hedbergdc280802013-09-16 13:05:13 +03004559 return 0;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004560}
4561
Mat Martineau8eb200b2012-10-23 15:24:17 -07004562static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4563{
4564 struct l2cap_move_chan_req req;
4565 u8 ident;
4566
4567 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4568
4569 ident = l2cap_get_ident(chan->conn);
4570 chan->ident = ident;
4571
4572 req.icid = cpu_to_le16(chan->scid);
4573 req.dest_amp_id = dest_amp_id;
4574
4575 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4576 &req);
4577
4578 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4579}
4580
Mat Martineau1500109b2012-10-23 15:24:15 -07004581static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004582{
4583 struct l2cap_move_chan_rsp rsp;
4584
Mat Martineau1500109b2012-10-23 15:24:15 -07004585 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004586
Mat Martineau1500109b2012-10-23 15:24:15 -07004587 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004588 rsp.result = cpu_to_le16(result);
4589
Mat Martineau1500109b2012-10-23 15:24:15 -07004590 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4591 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004592}
4593
Mat Martineau5b155ef2012-10-23 15:24:14 -07004594static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004595{
4596 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004597
Mat Martineau5b155ef2012-10-23 15:24:14 -07004598 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004599
Mat Martineau5b155ef2012-10-23 15:24:14 -07004600 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004601
Mat Martineau5b155ef2012-10-23 15:24:14 -07004602 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004603 cfm.result = cpu_to_le16(result);
4604
Mat Martineau5b155ef2012-10-23 15:24:14 -07004605 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4606 sizeof(cfm), &cfm);
4607
4608 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4609}
4610
4611static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4612{
4613 struct l2cap_move_chan_cfm cfm;
4614
4615 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4616
4617 cfm.icid = cpu_to_le16(icid);
4618 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4619
4620 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4621 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004622}
4623
4624static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004625 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004626{
4627 struct l2cap_move_chan_cfm_rsp rsp;
4628
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004629 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004630
4631 rsp.icid = cpu_to_le16(icid);
4632 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4633}
4634
Mat Martineau5f3847a2012-10-23 15:24:12 -07004635static void __release_logical_link(struct l2cap_chan *chan)
4636{
4637 chan->hs_hchan = NULL;
4638 chan->hs_hcon = NULL;
4639
4640 /* Placeholder - release the logical link */
4641}
4642
Mat Martineau1500109b2012-10-23 15:24:15 -07004643static void l2cap_logical_fail(struct l2cap_chan *chan)
4644{
4645 /* Logical link setup failed */
4646 if (chan->state != BT_CONNECTED) {
4647 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004648 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004649 return;
4650 }
4651
4652 switch (chan->move_role) {
4653 case L2CAP_MOVE_ROLE_RESPONDER:
4654 l2cap_move_done(chan);
4655 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4656 break;
4657 case L2CAP_MOVE_ROLE_INITIATOR:
4658 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4659 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4660 /* Remote has only sent pending or
4661 * success responses, clean up
4662 */
4663 l2cap_move_done(chan);
4664 }
4665
4666 /* Other amp move states imply that the move
4667 * has already aborted
4668 */
4669 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4670 break;
4671 }
4672}
4673
4674static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4675 struct hci_chan *hchan)
4676{
4677 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004678
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004679 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004680 chan->hs_hcon->l2cap_data = chan->conn;
4681
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004682 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004683
4684 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004685 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004686
4687 set_default_fcs(chan);
4688
4689 err = l2cap_ertm_init(chan);
4690 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004691 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004692 else
4693 l2cap_chan_ready(chan);
4694 }
4695}
4696
4697static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4698 struct hci_chan *hchan)
4699{
4700 chan->hs_hcon = hchan->conn;
4701 chan->hs_hcon->l2cap_data = chan->conn;
4702
4703 BT_DBG("move_state %d", chan->move_state);
4704
4705 switch (chan->move_state) {
4706 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4707 /* Move confirm will be sent after a success
4708 * response is received
4709 */
4710 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4711 break;
4712 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4713 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4714 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4715 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4716 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4717 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4718 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4719 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4720 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4721 }
4722 break;
4723 default:
4724 /* Move was not in expected state, free the channel */
4725 __release_logical_link(chan);
4726
4727 chan->move_state = L2CAP_MOVE_STABLE;
4728 }
4729}
4730
4731/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004732void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4733 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004734{
Mat Martineau1500109b2012-10-23 15:24:15 -07004735 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4736
4737 if (status) {
4738 l2cap_logical_fail(chan);
4739 __release_logical_link(chan);
4740 return;
4741 }
4742
4743 if (chan->state != BT_CONNECTED) {
4744 /* Ignore logical link if channel is on BR/EDR */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004745 if (chan->local_amp_id != AMP_ID_BREDR)
Mat Martineau1500109b2012-10-23 15:24:15 -07004746 l2cap_logical_finish_create(chan, hchan);
4747 } else {
4748 l2cap_logical_finish_move(chan, hchan);
4749 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004750}
4751
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004752void l2cap_move_start(struct l2cap_chan *chan)
4753{
4754 BT_DBG("chan %p", chan);
4755
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004756 if (chan->local_amp_id == AMP_ID_BREDR) {
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004757 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4758 return;
4759 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4760 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4761 /* Placeholder - start physical link setup */
4762 } else {
4763 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4764 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4765 chan->move_id = 0;
4766 l2cap_move_setup(chan);
4767 l2cap_send_move_chan_req(chan, 0);
4768 }
4769}
4770
Mat Martineau8eb200b2012-10-23 15:24:17 -07004771static void l2cap_do_create(struct l2cap_chan *chan, int result,
4772 u8 local_amp_id, u8 remote_amp_id)
4773{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004774 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4775 local_amp_id, remote_amp_id);
4776
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004777 chan->fcs = L2CAP_FCS_NONE;
4778
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004779 /* Outgoing channel on AMP */
4780 if (chan->state == BT_CONNECT) {
4781 if (result == L2CAP_CR_SUCCESS) {
4782 chan->local_amp_id = local_amp_id;
4783 l2cap_send_create_chan_req(chan, remote_amp_id);
4784 } else {
4785 /* Revert to BR/EDR connect */
4786 l2cap_send_conn_req(chan);
4787 }
4788
4789 return;
4790 }
4791
4792 /* Incoming channel on AMP */
4793 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004794 struct l2cap_conn_rsp rsp;
4795 char buf[128];
4796 rsp.scid = cpu_to_le16(chan->dcid);
4797 rsp.dcid = cpu_to_le16(chan->scid);
4798
Mat Martineau8eb200b2012-10-23 15:24:17 -07004799 if (result == L2CAP_CR_SUCCESS) {
4800 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004801 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4802 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004803 } else {
4804 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004805 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4806 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004807 }
4808
4809 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4810 sizeof(rsp), &rsp);
4811
4812 if (result == L2CAP_CR_SUCCESS) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004813 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004814 set_bit(CONF_REQ_SENT, &chan->conf_state);
4815 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4816 L2CAP_CONF_REQ,
4817 l2cap_build_conf_req(chan, buf), buf);
4818 chan->num_conf_req++;
4819 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004820 }
4821}
4822
4823static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4824 u8 remote_amp_id)
4825{
4826 l2cap_move_setup(chan);
4827 chan->move_id = local_amp_id;
4828 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4829
4830 l2cap_send_move_chan_req(chan, remote_amp_id);
4831}
4832
4833static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4834{
4835 struct hci_chan *hchan = NULL;
4836
4837 /* Placeholder - get hci_chan for logical link */
4838
4839 if (hchan) {
4840 if (hchan->state == BT_CONNECTED) {
4841 /* Logical link is ready to go */
4842 chan->hs_hcon = hchan->conn;
4843 chan->hs_hcon->l2cap_data = chan->conn;
4844 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4845 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4846
4847 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4848 } else {
4849 /* Wait for logical link to be ready */
4850 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4851 }
4852 } else {
4853 /* Logical link not available */
4854 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4855 }
4856}
4857
4858static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4859{
4860 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4861 u8 rsp_result;
4862 if (result == -EINVAL)
4863 rsp_result = L2CAP_MR_BAD_ID;
4864 else
4865 rsp_result = L2CAP_MR_NOT_ALLOWED;
4866
4867 l2cap_send_move_chan_rsp(chan, rsp_result);
4868 }
4869
4870 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4871 chan->move_state = L2CAP_MOVE_STABLE;
4872
4873 /* Restart data transmission */
4874 l2cap_ertm_send(chan);
4875}
4876
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004877/* Invoke with locked chan */
4878void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004879{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004880 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004881 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004882
Mat Martineau8eb200b2012-10-23 15:24:17 -07004883 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4884 chan, result, local_amp_id, remote_amp_id);
4885
Mat Martineau8eb200b2012-10-23 15:24:17 -07004886 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4887 l2cap_chan_unlock(chan);
4888 return;
4889 }
4890
4891 if (chan->state != BT_CONNECTED) {
4892 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4893 } else if (result != L2CAP_MR_SUCCESS) {
4894 l2cap_do_move_cancel(chan, result);
4895 } else {
4896 switch (chan->move_role) {
4897 case L2CAP_MOVE_ROLE_INITIATOR:
4898 l2cap_do_move_initiate(chan, local_amp_id,
4899 remote_amp_id);
4900 break;
4901 case L2CAP_MOVE_ROLE_RESPONDER:
4902 l2cap_do_move_respond(chan, result);
4903 break;
4904 default:
4905 l2cap_do_move_cancel(chan, result);
4906 break;
4907 }
4908 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004909}
4910
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004911static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004912 struct l2cap_cmd_hdr *cmd,
4913 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004914{
4915 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004916 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004917 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004918 u16 icid = 0;
4919 u16 result = L2CAP_MR_NOT_ALLOWED;
4920
4921 if (cmd_len != sizeof(*req))
4922 return -EPROTO;
4923
4924 icid = le16_to_cpu(req->icid);
4925
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004926 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004927
Marcel Holtmann848566b2013-10-01 22:59:22 -07004928 if (!conn->hs_enabled)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004929 return -EINVAL;
4930
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004931 chan = l2cap_get_chan_by_dcid(conn, icid);
4932 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004933 rsp.icid = cpu_to_le16(icid);
4934 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4935 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4936 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004937 return 0;
4938 }
4939
Mat Martineau1500109b2012-10-23 15:24:15 -07004940 chan->ident = cmd->ident;
4941
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004942 if (chan->scid < L2CAP_CID_DYN_START ||
4943 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4944 (chan->mode != L2CAP_MODE_ERTM &&
4945 chan->mode != L2CAP_MODE_STREAMING)) {
4946 result = L2CAP_MR_NOT_ALLOWED;
4947 goto send_move_response;
4948 }
4949
4950 if (chan->local_amp_id == req->dest_amp_id) {
4951 result = L2CAP_MR_SAME_ID;
4952 goto send_move_response;
4953 }
4954
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004955 if (req->dest_amp_id != AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004956 struct hci_dev *hdev;
4957 hdev = hci_dev_get(req->dest_amp_id);
4958 if (!hdev || hdev->dev_type != HCI_AMP ||
4959 !test_bit(HCI_UP, &hdev->flags)) {
4960 if (hdev)
4961 hci_dev_put(hdev);
4962
4963 result = L2CAP_MR_BAD_ID;
4964 goto send_move_response;
4965 }
4966 hci_dev_put(hdev);
4967 }
4968
4969 /* Detect a move collision. Only send a collision response
4970 * if this side has "lost", otherwise proceed with the move.
4971 * The winner has the larger bd_addr.
4972 */
4973 if ((__chan_is_moving(chan) ||
4974 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
Marcel Holtmann6f59b902013-10-13 05:24:01 -07004975 bacmp(&conn->hcon->src, &conn->hcon->dst) > 0) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004976 result = L2CAP_MR_COLLISION;
4977 goto send_move_response;
4978 }
4979
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004980 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4981 l2cap_move_setup(chan);
4982 chan->move_id = req->dest_amp_id;
4983 icid = chan->dcid;
4984
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004985 if (req->dest_amp_id == AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004986 /* Moving to BR/EDR */
4987 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4988 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4989 result = L2CAP_MR_PEND;
4990 } else {
4991 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4992 result = L2CAP_MR_SUCCESS;
4993 }
4994 } else {
4995 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4996 /* Placeholder - uncomment when amp functions are available */
4997 /*amp_accept_physical(chan, req->dest_amp_id);*/
4998 result = L2CAP_MR_PEND;
4999 }
5000
5001send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07005002 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005003
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005004 l2cap_chan_unlock(chan);
5005
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005006 return 0;
5007}
5008
Mat Martineau5b155ef2012-10-23 15:24:14 -07005009static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
5010{
5011 struct l2cap_chan *chan;
5012 struct hci_chan *hchan = NULL;
5013
5014 chan = l2cap_get_chan_by_scid(conn, icid);
5015 if (!chan) {
5016 l2cap_send_move_chan_cfm_icid(conn, icid);
5017 return;
5018 }
5019
5020 __clear_chan_timer(chan);
5021 if (result == L2CAP_MR_PEND)
5022 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
5023
5024 switch (chan->move_state) {
5025 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
5026 /* Move confirm will be sent when logical link
5027 * is complete.
5028 */
5029 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5030 break;
5031 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
5032 if (result == L2CAP_MR_PEND) {
5033 break;
5034 } else if (test_bit(CONN_LOCAL_BUSY,
5035 &chan->conn_state)) {
5036 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
5037 } else {
5038 /* Logical link is up or moving to BR/EDR,
5039 * proceed with move
5040 */
5041 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
5042 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5043 }
5044 break;
5045 case L2CAP_MOVE_WAIT_RSP:
5046 /* Moving to AMP */
5047 if (result == L2CAP_MR_SUCCESS) {
5048 /* Remote is ready, send confirm immediately
5049 * after logical link is ready
5050 */
5051 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5052 } else {
5053 /* Both logical link and move success
5054 * are required to confirm
5055 */
5056 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
5057 }
5058
5059 /* Placeholder - get hci_chan for logical link */
5060 if (!hchan) {
5061 /* Logical link not available */
5062 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5063 break;
5064 }
5065
5066 /* If the logical link is not yet connected, do not
5067 * send confirmation.
5068 */
5069 if (hchan->state != BT_CONNECTED)
5070 break;
5071
5072 /* Logical link is already ready to go */
5073
5074 chan->hs_hcon = hchan->conn;
5075 chan->hs_hcon->l2cap_data = chan->conn;
5076
5077 if (result == L2CAP_MR_SUCCESS) {
5078 /* Can confirm now */
5079 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5080 } else {
5081 /* Now only need move success
5082 * to confirm
5083 */
5084 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
5085 }
5086
5087 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5088 break;
5089 default:
5090 /* Any other amp move state means the move failed. */
5091 chan->move_id = chan->local_amp_id;
5092 l2cap_move_done(chan);
5093 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5094 }
5095
5096 l2cap_chan_unlock(chan);
5097}
5098
5099static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5100 u16 result)
5101{
5102 struct l2cap_chan *chan;
5103
5104 chan = l2cap_get_chan_by_ident(conn, ident);
5105 if (!chan) {
5106 /* Could not locate channel, icid is best guess */
5107 l2cap_send_move_chan_cfm_icid(conn, icid);
5108 return;
5109 }
5110
5111 __clear_chan_timer(chan);
5112
5113 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5114 if (result == L2CAP_MR_COLLISION) {
5115 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5116 } else {
5117 /* Cleanup - cancel move */
5118 chan->move_id = chan->local_amp_id;
5119 l2cap_move_done(chan);
5120 }
5121 }
5122
5123 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5124
5125 l2cap_chan_unlock(chan);
5126}
5127
5128static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5129 struct l2cap_cmd_hdr *cmd,
5130 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005131{
5132 struct l2cap_move_chan_rsp *rsp = data;
5133 u16 icid, result;
5134
5135 if (cmd_len != sizeof(*rsp))
5136 return -EPROTO;
5137
5138 icid = le16_to_cpu(rsp->icid);
5139 result = le16_to_cpu(rsp->result);
5140
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005141 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005142
Mat Martineau5b155ef2012-10-23 15:24:14 -07005143 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5144 l2cap_move_continue(conn, icid, result);
5145 else
5146 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005147
5148 return 0;
5149}
5150
Mat Martineau5f3847a2012-10-23 15:24:12 -07005151static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5152 struct l2cap_cmd_hdr *cmd,
5153 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005154{
5155 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005156 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005157 u16 icid, result;
5158
5159 if (cmd_len != sizeof(*cfm))
5160 return -EPROTO;
5161
5162 icid = le16_to_cpu(cfm->icid);
5163 result = le16_to_cpu(cfm->result);
5164
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005165 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005166
Mat Martineau5f3847a2012-10-23 15:24:12 -07005167 chan = l2cap_get_chan_by_dcid(conn, icid);
5168 if (!chan) {
5169 /* Spec requires a response even if the icid was not found */
5170 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5171 return 0;
5172 }
5173
5174 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5175 if (result == L2CAP_MC_CONFIRMED) {
5176 chan->local_amp_id = chan->move_id;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005177 if (chan->local_amp_id == AMP_ID_BREDR)
Mat Martineau5f3847a2012-10-23 15:24:12 -07005178 __release_logical_link(chan);
5179 } else {
5180 chan->move_id = chan->local_amp_id;
5181 }
5182
5183 l2cap_move_done(chan);
5184 }
5185
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005186 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5187
Mat Martineau5f3847a2012-10-23 15:24:12 -07005188 l2cap_chan_unlock(chan);
5189
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005190 return 0;
5191}
5192
5193static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005194 struct l2cap_cmd_hdr *cmd,
5195 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005196{
5197 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005198 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005199 u16 icid;
5200
5201 if (cmd_len != sizeof(*rsp))
5202 return -EPROTO;
5203
5204 icid = le16_to_cpu(rsp->icid);
5205
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005206 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005207
Mat Martineau3fd71a02012-10-23 15:24:16 -07005208 chan = l2cap_get_chan_by_scid(conn, icid);
5209 if (!chan)
5210 return 0;
5211
5212 __clear_chan_timer(chan);
5213
5214 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5215 chan->local_amp_id = chan->move_id;
5216
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005217 if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan)
Mat Martineau3fd71a02012-10-23 15:24:16 -07005218 __release_logical_link(chan);
5219
5220 l2cap_move_done(chan);
5221 }
5222
5223 l2cap_chan_unlock(chan);
5224
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005225 return 0;
5226}
5227
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005228static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005229 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005230{
5231 u16 max_latency;
5232
5233 if (min > max || min < 6 || max > 3200)
5234 return -EINVAL;
5235
5236 if (to_multiplier < 10 || to_multiplier > 3200)
5237 return -EINVAL;
5238
5239 if (max >= to_multiplier * 8)
5240 return -EINVAL;
5241
5242 max_latency = (to_multiplier * 8 / max) - 1;
5243 if (latency > 499 || latency > max_latency)
5244 return -EINVAL;
5245
5246 return 0;
5247}
5248
5249static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005250 struct l2cap_cmd_hdr *cmd,
Johan Hedberg203e6392013-05-15 10:07:15 +03005251 u16 cmd_len, u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005252{
5253 struct hci_conn *hcon = conn->hcon;
5254 struct l2cap_conn_param_update_req *req;
5255 struct l2cap_conn_param_update_rsp rsp;
Johan Hedberg203e6392013-05-15 10:07:15 +03005256 u16 min, max, latency, to_multiplier;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005257 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005258
5259 if (!(hcon->link_mode & HCI_LM_MASTER))
5260 return -EINVAL;
5261
Claudio Takahaside731152011-02-11 19:28:55 -02005262 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5263 return -EPROTO;
5264
5265 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005266 min = __le16_to_cpu(req->min);
5267 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005268 latency = __le16_to_cpu(req->latency);
5269 to_multiplier = __le16_to_cpu(req->to_multiplier);
5270
5271 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 +01005272 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005273
5274 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005275
5276 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5277 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005278 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005279 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005280 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005281
5282 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005283 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005284
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005285 if (!err)
5286 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5287
Claudio Takahaside731152011-02-11 19:28:55 -02005288 return 0;
5289}
5290
Johan Hedbergf1496de2013-05-13 14:15:56 +03005291static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
5292 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5293 u8 *data)
5294{
5295 struct l2cap_le_conn_rsp *rsp = (struct l2cap_le_conn_rsp *) data;
5296 u16 dcid, mtu, mps, credits, result;
5297 struct l2cap_chan *chan;
5298 int err;
5299
5300 if (cmd_len < sizeof(*rsp))
5301 return -EPROTO;
5302
5303 dcid = __le16_to_cpu(rsp->dcid);
5304 mtu = __le16_to_cpu(rsp->mtu);
5305 mps = __le16_to_cpu(rsp->mps);
5306 credits = __le16_to_cpu(rsp->credits);
5307 result = __le16_to_cpu(rsp->result);
5308
5309 if (result == L2CAP_CR_SUCCESS && (mtu < 23 || mps < 23))
5310 return -EPROTO;
5311
5312 BT_DBG("dcid 0x%4.4x mtu %u mps %u credits %u result 0x%2.2x",
5313 dcid, mtu, mps, credits, result);
5314
5315 mutex_lock(&conn->chan_lock);
5316
5317 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
5318 if (!chan) {
5319 err = -EBADSLT;
5320 goto unlock;
5321 }
5322
5323 err = 0;
5324
5325 l2cap_chan_lock(chan);
5326
5327 switch (result) {
5328 case L2CAP_CR_SUCCESS:
5329 chan->ident = 0;
5330 chan->dcid = dcid;
5331 chan->omtu = mtu;
5332 chan->remote_mps = mps;
5333 l2cap_chan_ready(chan);
5334 break;
5335
5336 default:
5337 l2cap_chan_del(chan, ECONNREFUSED);
5338 break;
5339 }
5340
5341 l2cap_chan_unlock(chan);
5342
5343unlock:
5344 mutex_unlock(&conn->chan_lock);
5345
5346 return err;
5347}
5348
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005349static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005350 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5351 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005352{
5353 int err = 0;
5354
5355 switch (cmd->code) {
5356 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005357 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005358 break;
5359
5360 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005361 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005362 break;
5363
5364 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005365 case L2CAP_CREATE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005366 l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005367 break;
5368
5369 case L2CAP_CONF_REQ:
5370 err = l2cap_config_req(conn, cmd, cmd_len, data);
5371 break;
5372
5373 case L2CAP_CONF_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005374 l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005375 break;
5376
5377 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005378 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005379 break;
5380
5381 case L2CAP_DISCONN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005382 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005383 break;
5384
5385 case L2CAP_ECHO_REQ:
5386 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5387 break;
5388
5389 case L2CAP_ECHO_RSP:
5390 break;
5391
5392 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005393 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005394 break;
5395
5396 case L2CAP_INFO_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005397 l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005398 break;
5399
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005400 case L2CAP_CREATE_CHAN_REQ:
5401 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5402 break;
5403
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005404 case L2CAP_MOVE_CHAN_REQ:
5405 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5406 break;
5407
5408 case L2CAP_MOVE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005409 l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005410 break;
5411
5412 case L2CAP_MOVE_CHAN_CFM:
5413 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5414 break;
5415
5416 case L2CAP_MOVE_CHAN_CFM_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005417 l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005418 break;
5419
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005420 default:
5421 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5422 err = -EINVAL;
5423 break;
5424 }
5425
5426 return err;
5427}
5428
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005429static int l2cap_le_connect_req(struct l2cap_conn *conn,
5430 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5431 u8 *data)
5432{
5433 struct l2cap_le_conn_req *req = (struct l2cap_le_conn_req *) data;
5434 struct l2cap_le_conn_rsp rsp;
5435 struct l2cap_chan *chan, *pchan;
5436 u16 dcid, scid, mtu, mps;
5437 __le16 psm;
5438 u8 result;
5439
5440 if (cmd_len != sizeof(*req))
5441 return -EPROTO;
5442
5443 scid = __le16_to_cpu(req->scid);
5444 mtu = __le16_to_cpu(req->mtu);
5445 mps = __le16_to_cpu(req->mps);
5446 psm = req->psm;
5447 dcid = 0;
5448
5449 if (mtu < 23 || mps < 23)
5450 return -EPROTO;
5451
5452 BT_DBG("psm 0x%2.2x scid 0x%4.4x mtu %u mps %u", __le16_to_cpu(psm),
5453 scid, mtu, mps);
5454
5455 /* Check if we have socket listening on psm */
5456 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
5457 &conn->hcon->dst, LE_LINK);
5458 if (!pchan) {
5459 result = L2CAP_CR_BAD_PSM;
5460 chan = NULL;
5461 goto response;
5462 }
5463
5464 mutex_lock(&conn->chan_lock);
5465 l2cap_chan_lock(pchan);
5466
5467 if (!smp_sufficient_security(conn->hcon, pchan->sec_level)) {
5468 result = L2CAP_CR_AUTHENTICATION;
5469 chan = NULL;
5470 goto response_unlock;
5471 }
5472
5473 /* Check if we already have channel with that dcid */
5474 if (__l2cap_get_chan_by_dcid(conn, scid)) {
5475 result = L2CAP_CR_NO_MEM;
5476 chan = NULL;
5477 goto response_unlock;
5478 }
5479
5480 chan = pchan->ops->new_connection(pchan);
5481 if (!chan) {
5482 result = L2CAP_CR_NO_MEM;
5483 goto response_unlock;
5484 }
5485
5486 bacpy(&chan->src, &conn->hcon->src);
5487 bacpy(&chan->dst, &conn->hcon->dst);
5488 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
5489 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
5490 chan->psm = psm;
5491 chan->dcid = scid;
5492 chan->omtu = mtu;
5493 chan->remote_mps = mps;
5494
5495 __l2cap_chan_add(conn, chan);
5496 dcid = chan->scid;
5497
5498 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
5499
5500 chan->ident = cmd->ident;
5501
5502 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
5503 l2cap_state_change(chan, BT_CONNECT2);
5504 result = L2CAP_CR_PEND;
5505 chan->ops->defer(chan);
5506 } else {
5507 l2cap_chan_ready(chan);
5508 result = L2CAP_CR_SUCCESS;
5509 }
5510
5511response_unlock:
5512 l2cap_chan_unlock(pchan);
5513 mutex_unlock(&conn->chan_lock);
5514
5515 if (result == L2CAP_CR_PEND)
5516 return 0;
5517
5518response:
5519 if (chan) {
5520 rsp.mtu = cpu_to_le16(chan->imtu);
5521 rsp.mps = __constant_cpu_to_le16(L2CAP_LE_DEFAULT_MPS);
5522 } else {
5523 rsp.mtu = 0;
5524 rsp.mps = 0;
5525 }
5526
5527 rsp.dcid = cpu_to_le16(dcid);
5528 rsp.credits = __constant_cpu_to_le16(L2CAP_LE_MAX_CREDITS);
5529 rsp.result = cpu_to_le16(result);
5530
5531 l2cap_send_cmd(conn, cmd->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), &rsp);
5532
5533 return 0;
5534}
5535
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005536static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Johan Hedberg203e6392013-05-15 10:07:15 +03005537 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5538 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005539{
5540 switch (cmd->code) {
5541 case L2CAP_COMMAND_REJ:
5542 return 0;
5543
5544 case L2CAP_CONN_PARAM_UPDATE_REQ:
Johan Hedberg203e6392013-05-15 10:07:15 +03005545 return l2cap_conn_param_update_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005546
5547 case L2CAP_CONN_PARAM_UPDATE_RSP:
5548 return 0;
5549
Johan Hedbergf1496de2013-05-13 14:15:56 +03005550 case L2CAP_LE_CONN_RSP:
5551 l2cap_le_connect_rsp(conn, cmd, cmd_len, data);
5552 return 0;
5553
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005554 case L2CAP_LE_CONN_REQ:
5555 return l2cap_le_connect_req(conn, cmd, cmd_len, data);
5556
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005557 default:
5558 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5559 return -EINVAL;
5560 }
5561}
5562
Johan Hedbergc5623552013-04-29 19:35:33 +03005563static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5564 struct sk_buff *skb)
5565{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005566 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005567 struct l2cap_cmd_hdr *cmd;
5568 u16 len;
Johan Hedbergc5623552013-04-29 19:35:33 +03005569 int err;
5570
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005571 if (hcon->type != LE_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005572 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005573
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005574 if (skb->len < L2CAP_CMD_HDR_SIZE)
5575 goto drop;
Johan Hedbergc5623552013-04-29 19:35:33 +03005576
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005577 cmd = (void *) skb->data;
5578 skb_pull(skb, L2CAP_CMD_HDR_SIZE);
Johan Hedbergc5623552013-04-29 19:35:33 +03005579
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005580 len = le16_to_cpu(cmd->len);
Johan Hedbergc5623552013-04-29 19:35:33 +03005581
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005582 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, cmd->ident);
Johan Hedbergc5623552013-04-29 19:35:33 +03005583
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005584 if (len != skb->len || !cmd->ident) {
5585 BT_DBG("corrupted command");
5586 goto drop;
5587 }
Johan Hedbergc5623552013-04-29 19:35:33 +03005588
Johan Hedberg203e6392013-05-15 10:07:15 +03005589 err = l2cap_le_sig_cmd(conn, cmd, len, skb->data);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005590 if (err) {
5591 struct l2cap_cmd_rej_unk rej;
Johan Hedbergc5623552013-04-29 19:35:33 +03005592
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005593 BT_ERR("Wrong link type (%d)", err);
Johan Hedbergc5623552013-04-29 19:35:33 +03005594
Johan Hedberga5211492013-10-16 11:20:49 +03005595 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005596 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
5597 sizeof(rej), &rej);
Johan Hedbergc5623552013-04-29 19:35:33 +03005598 }
5599
Marcel Holtmann3b166292013-10-02 08:28:21 -07005600drop:
Johan Hedbergc5623552013-04-29 19:35:33 +03005601 kfree_skb(skb);
5602}
5603
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005604static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005605 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005606{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005607 struct hci_conn *hcon = conn->hcon;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005608 u8 *data = skb->data;
5609 int len = skb->len;
5610 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005611 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005612
5613 l2cap_raw_recv(conn, skb);
5614
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005615 if (hcon->type != ACL_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005616 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005617
Linus Torvalds1da177e2005-04-16 15:20:36 -07005618 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005619 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005620 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5621 data += L2CAP_CMD_HDR_SIZE;
5622 len -= L2CAP_CMD_HDR_SIZE;
5623
Al Viro88219a02007-07-29 00:17:25 -07005624 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005625
Gustavo Padovan2d792812012-10-06 10:07:01 +01005626 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5627 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005628
Al Viro88219a02007-07-29 00:17:25 -07005629 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005630 BT_DBG("corrupted command");
5631 break;
5632 }
5633
Johan Hedbergc5623552013-04-29 19:35:33 +03005634 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005635 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005636 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005637
5638 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005639
Johan Hedberga5211492013-10-16 11:20:49 +03005640 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005641 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5642 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005643 }
5644
Al Viro88219a02007-07-29 00:17:25 -07005645 data += cmd_len;
5646 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005647 }
5648
Marcel Holtmann3b166292013-10-02 08:28:21 -07005649drop:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005650 kfree_skb(skb);
5651}
5652
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005653static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005654{
5655 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005656 int hdr_size;
5657
5658 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5659 hdr_size = L2CAP_EXT_HDR_SIZE;
5660 else
5661 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005662
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005663 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005664 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005665 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5666 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5667
5668 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005669 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005670 }
5671 return 0;
5672}
5673
Mat Martineau6ea00482012-05-17 20:53:52 -07005674static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005675{
Mat Martineaue31f7632012-05-17 20:53:41 -07005676 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005677
Mat Martineaue31f7632012-05-17 20:53:41 -07005678 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005679
Mat Martineaue31f7632012-05-17 20:53:41 -07005680 memset(&control, 0, sizeof(control));
5681 control.sframe = 1;
5682 control.final = 1;
5683 control.reqseq = chan->buffer_seq;
5684 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005685
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005686 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005687 control.super = L2CAP_SUPER_RNR;
5688 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005689 }
5690
Mat Martineaue31f7632012-05-17 20:53:41 -07005691 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5692 chan->unacked_frames > 0)
5693 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005694
Mat Martineaue31f7632012-05-17 20:53:41 -07005695 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005696 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005697
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005698 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005699 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5700 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5701 * send it now.
5702 */
5703 control.super = L2CAP_SUPER_RR;
5704 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005705 }
5706}
5707
Gustavo Padovan2d792812012-10-06 10:07:01 +01005708static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5709 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005710{
Mat Martineau84084a32011-07-22 14:54:00 -07005711 /* skb->len reflects data in skb as well as all fragments
5712 * skb->data_len reflects only data in fragments
5713 */
5714 if (!skb_has_frag_list(skb))
5715 skb_shinfo(skb)->frag_list = new_frag;
5716
5717 new_frag->next = NULL;
5718
5719 (*last_frag)->next = new_frag;
5720 *last_frag = new_frag;
5721
5722 skb->len += new_frag->len;
5723 skb->data_len += new_frag->len;
5724 skb->truesize += new_frag->truesize;
5725}
5726
Mat Martineau4b51dae92012-05-17 20:53:37 -07005727static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5728 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005729{
5730 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005731
Mat Martineau4b51dae92012-05-17 20:53:37 -07005732 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005733 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005734 if (chan->sdu)
5735 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005736
Gustavo Padovan80b98022012-05-27 22:27:51 -03005737 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005738 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005739
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005740 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005741 if (chan->sdu)
5742 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005743
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005744 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005745 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005746
Mat Martineau84084a32011-07-22 14:54:00 -07005747 if (chan->sdu_len > chan->imtu) {
5748 err = -EMSGSIZE;
5749 break;
5750 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005751
Mat Martineau84084a32011-07-22 14:54:00 -07005752 if (skb->len >= chan->sdu_len)
5753 break;
5754
5755 chan->sdu = skb;
5756 chan->sdu_last_frag = skb;
5757
5758 skb = NULL;
5759 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005760 break;
5761
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005762 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005763 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005764 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005765
Mat Martineau84084a32011-07-22 14:54:00 -07005766 append_skb_frag(chan->sdu, skb,
5767 &chan->sdu_last_frag);
5768 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005769
Mat Martineau84084a32011-07-22 14:54:00 -07005770 if (chan->sdu->len >= chan->sdu_len)
5771 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005772
Mat Martineau84084a32011-07-22 14:54:00 -07005773 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005774 break;
5775
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005776 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005777 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005778 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005779
Mat Martineau84084a32011-07-22 14:54:00 -07005780 append_skb_frag(chan->sdu, skb,
5781 &chan->sdu_last_frag);
5782 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005783
Mat Martineau84084a32011-07-22 14:54:00 -07005784 if (chan->sdu->len != chan->sdu_len)
5785 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005786
Gustavo Padovan80b98022012-05-27 22:27:51 -03005787 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005788
Mat Martineau84084a32011-07-22 14:54:00 -07005789 if (!err) {
5790 /* Reassembly complete */
5791 chan->sdu = NULL;
5792 chan->sdu_last_frag = NULL;
5793 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005794 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005795 break;
5796 }
5797
Mat Martineau84084a32011-07-22 14:54:00 -07005798 if (err) {
5799 kfree_skb(skb);
5800 kfree_skb(chan->sdu);
5801 chan->sdu = NULL;
5802 chan->sdu_last_frag = NULL;
5803 chan->sdu_len = 0;
5804 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005805
Mat Martineau84084a32011-07-22 14:54:00 -07005806 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005807}
5808
Mat Martineau32b32732012-10-23 15:24:11 -07005809static int l2cap_resegment(struct l2cap_chan *chan)
5810{
5811 /* Placeholder */
5812 return 0;
5813}
5814
Mat Martineaue3281402011-07-07 09:39:02 -07005815void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132eb2010-06-21 19:39:50 -03005816{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005817 u8 event;
5818
5819 if (chan->mode != L2CAP_MODE_ERTM)
5820 return;
5821
5822 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005823 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005824}
5825
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005826static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5827{
Mat Martineau63838722012-05-17 20:53:45 -07005828 int err = 0;
5829 /* Pass sequential frames to l2cap_reassemble_sdu()
5830 * until a gap is encountered.
5831 */
5832
5833 BT_DBG("chan %p", chan);
5834
5835 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5836 struct sk_buff *skb;
5837 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5838 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5839
5840 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5841
5842 if (!skb)
5843 break;
5844
5845 skb_unlink(skb, &chan->srej_q);
5846 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5847 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5848 if (err)
5849 break;
5850 }
5851
5852 if (skb_queue_empty(&chan->srej_q)) {
5853 chan->rx_state = L2CAP_RX_STATE_RECV;
5854 l2cap_send_ack(chan);
5855 }
5856
5857 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005858}
5859
5860static void l2cap_handle_srej(struct l2cap_chan *chan,
5861 struct l2cap_ctrl *control)
5862{
Mat Martineauf80842a2012-05-17 20:53:46 -07005863 struct sk_buff *skb;
5864
5865 BT_DBG("chan %p, control %p", chan, control);
5866
5867 if (control->reqseq == chan->next_tx_seq) {
5868 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005869 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005870 return;
5871 }
5872
5873 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5874
5875 if (skb == NULL) {
5876 BT_DBG("Seq %d not available for retransmission",
5877 control->reqseq);
5878 return;
5879 }
5880
5881 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5882 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005883 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005884 return;
5885 }
5886
5887 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5888
5889 if (control->poll) {
5890 l2cap_pass_to_tx(chan, control);
5891
5892 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5893 l2cap_retransmit(chan, control);
5894 l2cap_ertm_send(chan);
5895
5896 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5897 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5898 chan->srej_save_reqseq = control->reqseq;
5899 }
5900 } else {
5901 l2cap_pass_to_tx_fbit(chan, control);
5902
5903 if (control->final) {
5904 if (chan->srej_save_reqseq != control->reqseq ||
5905 !test_and_clear_bit(CONN_SREJ_ACT,
5906 &chan->conn_state))
5907 l2cap_retransmit(chan, control);
5908 } else {
5909 l2cap_retransmit(chan, control);
5910 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5911 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5912 chan->srej_save_reqseq = control->reqseq;
5913 }
5914 }
5915 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005916}
5917
5918static void l2cap_handle_rej(struct l2cap_chan *chan,
5919 struct l2cap_ctrl *control)
5920{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005921 struct sk_buff *skb;
5922
5923 BT_DBG("chan %p, control %p", chan, control);
5924
5925 if (control->reqseq == chan->next_tx_seq) {
5926 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005927 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005928 return;
5929 }
5930
5931 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5932
5933 if (chan->max_tx && skb &&
5934 bt_cb(skb)->control.retries >= chan->max_tx) {
5935 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005936 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005937 return;
5938 }
5939
5940 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5941
5942 l2cap_pass_to_tx(chan, control);
5943
5944 if (control->final) {
5945 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5946 l2cap_retransmit_all(chan, control);
5947 } else {
5948 l2cap_retransmit_all(chan, control);
5949 l2cap_ertm_send(chan);
5950 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5951 set_bit(CONN_REJ_ACT, &chan->conn_state);
5952 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005953}
5954
Mat Martineau4b51dae92012-05-17 20:53:37 -07005955static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5956{
5957 BT_DBG("chan %p, txseq %d", chan, txseq);
5958
5959 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5960 chan->expected_tx_seq);
5961
5962 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5963 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005964 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005965 /* See notes below regarding "double poll" and
5966 * invalid packets.
5967 */
5968 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5969 BT_DBG("Invalid/Ignore - after SREJ");
5970 return L2CAP_TXSEQ_INVALID_IGNORE;
5971 } else {
5972 BT_DBG("Invalid - in window after SREJ sent");
5973 return L2CAP_TXSEQ_INVALID;
5974 }
5975 }
5976
5977 if (chan->srej_list.head == txseq) {
5978 BT_DBG("Expected SREJ");
5979 return L2CAP_TXSEQ_EXPECTED_SREJ;
5980 }
5981
5982 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5983 BT_DBG("Duplicate SREJ - txseq already stored");
5984 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5985 }
5986
5987 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5988 BT_DBG("Unexpected SREJ - not requested");
5989 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5990 }
5991 }
5992
5993 if (chan->expected_tx_seq == txseq) {
5994 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5995 chan->tx_win) {
5996 BT_DBG("Invalid - txseq outside tx window");
5997 return L2CAP_TXSEQ_INVALID;
5998 } else {
5999 BT_DBG("Expected");
6000 return L2CAP_TXSEQ_EXPECTED;
6001 }
6002 }
6003
6004 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01006005 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07006006 BT_DBG("Duplicate - expected_tx_seq later than txseq");
6007 return L2CAP_TXSEQ_DUPLICATE;
6008 }
6009
6010 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
6011 /* A source of invalid packets is a "double poll" condition,
6012 * where delays cause us to send multiple poll packets. If
6013 * the remote stack receives and processes both polls,
6014 * sequence numbers can wrap around in such a way that a
6015 * resent frame has a sequence number that looks like new data
6016 * with a sequence gap. This would trigger an erroneous SREJ
6017 * request.
6018 *
6019 * Fortunately, this is impossible with a tx window that's
6020 * less than half of the maximum sequence number, which allows
6021 * invalid frames to be safely ignored.
6022 *
6023 * With tx window sizes greater than half of the tx window
6024 * maximum, the frame is invalid and cannot be ignored. This
6025 * causes a disconnect.
6026 */
6027
6028 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
6029 BT_DBG("Invalid/Ignore - txseq outside tx window");
6030 return L2CAP_TXSEQ_INVALID_IGNORE;
6031 } else {
6032 BT_DBG("Invalid - txseq outside tx window");
6033 return L2CAP_TXSEQ_INVALID;
6034 }
6035 } else {
6036 BT_DBG("Unexpected - txseq indicates missing frames");
6037 return L2CAP_TXSEQ_UNEXPECTED;
6038 }
6039}
6040
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006041static int l2cap_rx_state_recv(struct l2cap_chan *chan,
6042 struct l2cap_ctrl *control,
6043 struct sk_buff *skb, u8 event)
6044{
6045 int err = 0;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006046 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006047
6048 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6049 event);
6050
6051 switch (event) {
6052 case L2CAP_EV_RECV_IFRAME:
6053 switch (l2cap_classify_txseq(chan, control->txseq)) {
6054 case L2CAP_TXSEQ_EXPECTED:
6055 l2cap_pass_to_tx(chan, control);
6056
6057 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6058 BT_DBG("Busy, discarding expected seq %d",
6059 control->txseq);
6060 break;
6061 }
6062
6063 chan->expected_tx_seq = __next_seq(chan,
6064 control->txseq);
6065
6066 chan->buffer_seq = chan->expected_tx_seq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006067 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006068
6069 err = l2cap_reassemble_sdu(chan, skb, control);
6070 if (err)
6071 break;
6072
6073 if (control->final) {
6074 if (!test_and_clear_bit(CONN_REJ_ACT,
6075 &chan->conn_state)) {
6076 control->final = 0;
6077 l2cap_retransmit_all(chan, control);
6078 l2cap_ertm_send(chan);
6079 }
6080 }
6081
6082 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
6083 l2cap_send_ack(chan);
6084 break;
6085 case L2CAP_TXSEQ_UNEXPECTED:
6086 l2cap_pass_to_tx(chan, control);
6087
6088 /* Can't issue SREJ frames in the local busy state.
6089 * Drop this frame, it will be seen as missing
6090 * when local busy is exited.
6091 */
6092 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6093 BT_DBG("Busy, discarding unexpected seq %d",
6094 control->txseq);
6095 break;
6096 }
6097
6098 /* There was a gap in the sequence, so an SREJ
6099 * must be sent for each missing frame. The
6100 * current frame is stored for later use.
6101 */
6102 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006103 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006104 BT_DBG("Queued %p (queue len %d)", skb,
6105 skb_queue_len(&chan->srej_q));
6106
6107 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
6108 l2cap_seq_list_clear(&chan->srej_list);
6109 l2cap_send_srej(chan, control->txseq);
6110
6111 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
6112 break;
6113 case L2CAP_TXSEQ_DUPLICATE:
6114 l2cap_pass_to_tx(chan, control);
6115 break;
6116 case L2CAP_TXSEQ_INVALID_IGNORE:
6117 break;
6118 case L2CAP_TXSEQ_INVALID:
6119 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006120 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006121 break;
6122 }
6123 break;
6124 case L2CAP_EV_RECV_RR:
6125 l2cap_pass_to_tx(chan, control);
6126 if (control->final) {
6127 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6128
Mat Martineaue6a3ee62012-10-23 15:24:22 -07006129 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
6130 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006131 control->final = 0;
6132 l2cap_retransmit_all(chan, control);
6133 }
6134
6135 l2cap_ertm_send(chan);
6136 } else if (control->poll) {
6137 l2cap_send_i_or_rr_or_rnr(chan);
6138 } else {
6139 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6140 &chan->conn_state) &&
6141 chan->unacked_frames)
6142 __set_retrans_timer(chan);
6143
6144 l2cap_ertm_send(chan);
6145 }
6146 break;
6147 case L2CAP_EV_RECV_RNR:
6148 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6149 l2cap_pass_to_tx(chan, control);
6150 if (control && control->poll) {
6151 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6152 l2cap_send_rr_or_rnr(chan, 0);
6153 }
6154 __clear_retrans_timer(chan);
6155 l2cap_seq_list_clear(&chan->retrans_list);
6156 break;
6157 case L2CAP_EV_RECV_REJ:
6158 l2cap_handle_rej(chan, control);
6159 break;
6160 case L2CAP_EV_RECV_SREJ:
6161 l2cap_handle_srej(chan, control);
6162 break;
6163 default:
6164 break;
6165 }
6166
6167 if (skb && !skb_in_use) {
6168 BT_DBG("Freeing %p", skb);
6169 kfree_skb(skb);
6170 }
6171
6172 return err;
6173}
6174
6175static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
6176 struct l2cap_ctrl *control,
6177 struct sk_buff *skb, u8 event)
6178{
6179 int err = 0;
6180 u16 txseq = control->txseq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006181 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006182
6183 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6184 event);
6185
6186 switch (event) {
6187 case L2CAP_EV_RECV_IFRAME:
6188 switch (l2cap_classify_txseq(chan, txseq)) {
6189 case L2CAP_TXSEQ_EXPECTED:
6190 /* Keep frame for reassembly later */
6191 l2cap_pass_to_tx(chan, control);
6192 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006193 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006194 BT_DBG("Queued %p (queue len %d)", skb,
6195 skb_queue_len(&chan->srej_q));
6196
6197 chan->expected_tx_seq = __next_seq(chan, txseq);
6198 break;
6199 case L2CAP_TXSEQ_EXPECTED_SREJ:
6200 l2cap_seq_list_pop(&chan->srej_list);
6201
6202 l2cap_pass_to_tx(chan, control);
6203 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006204 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006205 BT_DBG("Queued %p (queue len %d)", skb,
6206 skb_queue_len(&chan->srej_q));
6207
6208 err = l2cap_rx_queued_iframes(chan);
6209 if (err)
6210 break;
6211
6212 break;
6213 case L2CAP_TXSEQ_UNEXPECTED:
6214 /* Got a frame that can't be reassembled yet.
6215 * Save it for later, and send SREJs to cover
6216 * the missing frames.
6217 */
6218 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006219 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006220 BT_DBG("Queued %p (queue len %d)", skb,
6221 skb_queue_len(&chan->srej_q));
6222
6223 l2cap_pass_to_tx(chan, control);
6224 l2cap_send_srej(chan, control->txseq);
6225 break;
6226 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
6227 /* This frame was requested with an SREJ, but
6228 * some expected retransmitted frames are
6229 * missing. Request retransmission of missing
6230 * SREJ'd frames.
6231 */
6232 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006233 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006234 BT_DBG("Queued %p (queue len %d)", skb,
6235 skb_queue_len(&chan->srej_q));
6236
6237 l2cap_pass_to_tx(chan, control);
6238 l2cap_send_srej_list(chan, control->txseq);
6239 break;
6240 case L2CAP_TXSEQ_DUPLICATE_SREJ:
6241 /* We've already queued this frame. Drop this copy. */
6242 l2cap_pass_to_tx(chan, control);
6243 break;
6244 case L2CAP_TXSEQ_DUPLICATE:
6245 /* Expecting a later sequence number, so this frame
6246 * was already received. Ignore it completely.
6247 */
6248 break;
6249 case L2CAP_TXSEQ_INVALID_IGNORE:
6250 break;
6251 case L2CAP_TXSEQ_INVALID:
6252 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006253 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006254 break;
6255 }
6256 break;
6257 case L2CAP_EV_RECV_RR:
6258 l2cap_pass_to_tx(chan, control);
6259 if (control->final) {
6260 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6261
6262 if (!test_and_clear_bit(CONN_REJ_ACT,
6263 &chan->conn_state)) {
6264 control->final = 0;
6265 l2cap_retransmit_all(chan, control);
6266 }
6267
6268 l2cap_ertm_send(chan);
6269 } else if (control->poll) {
6270 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6271 &chan->conn_state) &&
6272 chan->unacked_frames) {
6273 __set_retrans_timer(chan);
6274 }
6275
6276 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6277 l2cap_send_srej_tail(chan);
6278 } else {
6279 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6280 &chan->conn_state) &&
6281 chan->unacked_frames)
6282 __set_retrans_timer(chan);
6283
6284 l2cap_send_ack(chan);
6285 }
6286 break;
6287 case L2CAP_EV_RECV_RNR:
6288 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6289 l2cap_pass_to_tx(chan, control);
6290 if (control->poll) {
6291 l2cap_send_srej_tail(chan);
6292 } else {
6293 struct l2cap_ctrl rr_control;
6294 memset(&rr_control, 0, sizeof(rr_control));
6295 rr_control.sframe = 1;
6296 rr_control.super = L2CAP_SUPER_RR;
6297 rr_control.reqseq = chan->buffer_seq;
6298 l2cap_send_sframe(chan, &rr_control);
6299 }
6300
6301 break;
6302 case L2CAP_EV_RECV_REJ:
6303 l2cap_handle_rej(chan, control);
6304 break;
6305 case L2CAP_EV_RECV_SREJ:
6306 l2cap_handle_srej(chan, control);
6307 break;
6308 }
6309
6310 if (skb && !skb_in_use) {
6311 BT_DBG("Freeing %p", skb);
6312 kfree_skb(skb);
6313 }
6314
6315 return err;
6316}
6317
Mat Martineau32b32732012-10-23 15:24:11 -07006318static int l2cap_finish_move(struct l2cap_chan *chan)
6319{
6320 BT_DBG("chan %p", chan);
6321
6322 chan->rx_state = L2CAP_RX_STATE_RECV;
6323
6324 if (chan->hs_hcon)
6325 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6326 else
6327 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6328
6329 return l2cap_resegment(chan);
6330}
6331
6332static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6333 struct l2cap_ctrl *control,
6334 struct sk_buff *skb, u8 event)
6335{
6336 int err;
6337
6338 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6339 event);
6340
6341 if (!control->poll)
6342 return -EPROTO;
6343
6344 l2cap_process_reqseq(chan, control->reqseq);
6345
6346 if (!skb_queue_empty(&chan->tx_q))
6347 chan->tx_send_head = skb_peek(&chan->tx_q);
6348 else
6349 chan->tx_send_head = NULL;
6350
6351 /* Rewind next_tx_seq to the point expected
6352 * by the receiver.
6353 */
6354 chan->next_tx_seq = control->reqseq;
6355 chan->unacked_frames = 0;
6356
6357 err = l2cap_finish_move(chan);
6358 if (err)
6359 return err;
6360
6361 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6362 l2cap_send_i_or_rr_or_rnr(chan);
6363
6364 if (event == L2CAP_EV_RECV_IFRAME)
6365 return -EPROTO;
6366
6367 return l2cap_rx_state_recv(chan, control, NULL, event);
6368}
6369
6370static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6371 struct l2cap_ctrl *control,
6372 struct sk_buff *skb, u8 event)
6373{
6374 int err;
6375
6376 if (!control->final)
6377 return -EPROTO;
6378
6379 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6380
6381 chan->rx_state = L2CAP_RX_STATE_RECV;
6382 l2cap_process_reqseq(chan, control->reqseq);
6383
6384 if (!skb_queue_empty(&chan->tx_q))
6385 chan->tx_send_head = skb_peek(&chan->tx_q);
6386 else
6387 chan->tx_send_head = NULL;
6388
6389 /* Rewind next_tx_seq to the point expected
6390 * by the receiver.
6391 */
6392 chan->next_tx_seq = control->reqseq;
6393 chan->unacked_frames = 0;
6394
6395 if (chan->hs_hcon)
6396 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6397 else
6398 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6399
6400 err = l2cap_resegment(chan);
6401
6402 if (!err)
6403 err = l2cap_rx_state_recv(chan, control, skb, event);
6404
6405 return err;
6406}
6407
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006408static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6409{
6410 /* Make sure reqseq is for a packet that has been sent but not acked */
6411 u16 unacked;
6412
6413 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6414 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6415}
6416
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006417static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6418 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006419{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006420 int err = 0;
6421
6422 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6423 control, skb, event, chan->rx_state);
6424
6425 if (__valid_reqseq(chan, control->reqseq)) {
6426 switch (chan->rx_state) {
6427 case L2CAP_RX_STATE_RECV:
6428 err = l2cap_rx_state_recv(chan, control, skb, event);
6429 break;
6430 case L2CAP_RX_STATE_SREJ_SENT:
6431 err = l2cap_rx_state_srej_sent(chan, control, skb,
6432 event);
6433 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006434 case L2CAP_RX_STATE_WAIT_P:
6435 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6436 break;
6437 case L2CAP_RX_STATE_WAIT_F:
6438 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6439 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006440 default:
6441 /* shut it down */
6442 break;
6443 }
6444 } else {
6445 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6446 control->reqseq, chan->next_tx_seq,
6447 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006448 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006449 }
6450
6451 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006452}
6453
6454static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6455 struct sk_buff *skb)
6456{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006457 int err = 0;
6458
6459 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6460 chan->rx_state);
6461
6462 if (l2cap_classify_txseq(chan, control->txseq) ==
6463 L2CAP_TXSEQ_EXPECTED) {
6464 l2cap_pass_to_tx(chan, control);
6465
6466 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6467 __next_seq(chan, chan->buffer_seq));
6468
6469 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6470
6471 l2cap_reassemble_sdu(chan, skb, control);
6472 } else {
6473 if (chan->sdu) {
6474 kfree_skb(chan->sdu);
6475 chan->sdu = NULL;
6476 }
6477 chan->sdu_last_frag = NULL;
6478 chan->sdu_len = 0;
6479
6480 if (skb) {
6481 BT_DBG("Freeing %p", skb);
6482 kfree_skb(skb);
6483 }
6484 }
6485
6486 chan->last_acked_seq = control->txseq;
6487 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6488
6489 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006490}
6491
6492static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6493{
6494 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6495 u16 len;
6496 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006497
Mat Martineaub76bbd62012-04-11 10:48:43 -07006498 __unpack_control(chan, skb);
6499
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006500 len = skb->len;
6501
6502 /*
6503 * We can just drop the corrupted I-frame here.
6504 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006505 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006506 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006507 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006508 goto drop;
6509
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006510 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006511 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006512
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006513 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006514 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006515
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006516 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006517 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006518 goto drop;
6519 }
6520
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006521 if (!control->sframe) {
6522 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006523
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006524 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6525 control->sar, control->reqseq, control->final,
6526 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006527
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006528 /* Validate F-bit - F=0 always valid, F=1 only
6529 * valid in TX WAIT_F
6530 */
6531 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006532 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006533
6534 if (chan->mode != L2CAP_MODE_STREAMING) {
6535 event = L2CAP_EV_RECV_IFRAME;
6536 err = l2cap_rx(chan, control, skb, event);
6537 } else {
6538 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006539 }
6540
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006541 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006542 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006543 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006544 const u8 rx_func_to_event[4] = {
6545 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6546 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6547 };
6548
6549 /* Only I-frames are expected in streaming mode */
6550 if (chan->mode == L2CAP_MODE_STREAMING)
6551 goto drop;
6552
6553 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6554 control->reqseq, control->final, control->poll,
6555 control->super);
6556
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006557 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006558 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006559 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006560 goto drop;
6561 }
6562
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006563 /* Validate F and P bits */
6564 if (control->final && (control->poll ||
6565 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6566 goto drop;
6567
6568 event = rx_func_to_event[control->super];
6569 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006570 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006571 }
6572
6573 return 0;
6574
6575drop:
6576 kfree_skb(skb);
6577 return 0;
6578}
6579
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006580static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6581 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006582{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006583 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006584
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006585 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006586 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006587 if (cid == L2CAP_CID_A2MP) {
6588 chan = a2mp_channel_create(conn, skb);
6589 if (!chan) {
6590 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006591 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006592 }
6593
6594 l2cap_chan_lock(chan);
6595 } else {
6596 BT_DBG("unknown cid 0x%4.4x", cid);
6597 /* Drop packet and return */
6598 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006599 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006600 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006601 }
6602
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006603 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006604
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006605 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006606 goto drop;
6607
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006608 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006609 case L2CAP_MODE_BASIC:
6610 /* If socket recv buffers overflows we drop data here
6611 * which is *bad* because L2CAP has to be reliable.
6612 * But we don't have any other choice. L2CAP doesn't
6613 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006614
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006615 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006616 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006617
Gustavo Padovan80b98022012-05-27 22:27:51 -03006618 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006619 goto done;
6620 break;
6621
6622 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006623 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006624 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006625 goto done;
6626
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006627 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006628 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006629 break;
6630 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006631
6632drop:
6633 kfree_skb(skb);
6634
6635done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006636 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006637}
6638
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006639static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6640 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006641{
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006642 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006643 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006644
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006645 if (hcon->type != ACL_LINK)
6646 goto drop;
6647
Johan Hedbergbf20fd42013-05-14 13:23:13 +03006648 chan = l2cap_global_chan_by_psm(0, psm, &hcon->src, &hcon->dst,
6649 ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006650 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006651 goto drop;
6652
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006653 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006654
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006655 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006656 goto drop;
6657
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006658 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006659 goto drop;
6660
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006661 /* Store remote BD_ADDR and PSM for msg_name */
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006662 bacpy(&bt_cb(skb)->bdaddr, &hcon->dst);
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006663 bt_cb(skb)->psm = psm;
6664
Gustavo Padovan80b98022012-05-27 22:27:51 -03006665 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006666 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006667
6668drop:
6669 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006670}
6671
Marcel Holtmann72f78352013-04-23 00:59:00 -07006672static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006673 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006674{
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006675 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006676 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006677
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006678 if (hcon->type != LE_LINK)
6679 goto drop;
6680
Johan Hedbergaf1c0132013-04-29 19:35:42 +03006681 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006682 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006683 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006684 goto drop;
6685
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006686 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006687
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07006688 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, hcon->dst_type))
6689 goto drop;
6690
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006691 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006692 goto drop;
6693
Gustavo Padovan80b98022012-05-27 22:27:51 -03006694 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006695 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006696
6697drop:
6698 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006699}
6700
Linus Torvalds1da177e2005-04-16 15:20:36 -07006701static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6702{
6703 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006704 u16 cid, len;
6705 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006706
6707 skb_pull(skb, L2CAP_HDR_SIZE);
6708 cid = __le16_to_cpu(lh->cid);
6709 len = __le16_to_cpu(lh->len);
6710
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006711 if (len != skb->len) {
6712 kfree_skb(skb);
6713 return;
6714 }
6715
Linus Torvalds1da177e2005-04-16 15:20:36 -07006716 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6717
6718 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006719 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006720 l2cap_sig_channel(conn, skb);
6721 break;
6722
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006723 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006724 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006725 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006726 l2cap_conless_channel(conn, psm, skb);
6727 break;
6728
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006729 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006730 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006731 break;
6732
Marcel Holtmanna2877622013-10-02 23:46:54 -07006733 case L2CAP_CID_LE_SIGNALING:
6734 l2cap_le_sig_channel(conn, skb);
6735 break;
6736
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006737 case L2CAP_CID_SMP:
6738 if (smp_sig_channel(conn, skb))
6739 l2cap_conn_del(conn->hcon, EACCES);
6740 break;
6741
Linus Torvalds1da177e2005-04-16 15:20:36 -07006742 default:
6743 l2cap_data_channel(conn, cid, skb);
6744 break;
6745 }
6746}
6747
6748/* ---- L2CAP interface with lower layer (HCI) ---- */
6749
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006750int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006751{
6752 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006753 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006754
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006755 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006756
6757 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006758 read_lock(&chan_list_lock);
6759 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006760 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006761 continue;
6762
Marcel Holtmann7eafc592013-10-13 08:12:47 -07006763 if (!bacmp(&c->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006764 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006765 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006766 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006767 exact++;
Marcel Holtmann7eafc592013-10-13 08:12:47 -07006768 } else if (!bacmp(&c->src, BDADDR_ANY)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006769 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006770 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006771 lm2 |= HCI_LM_MASTER;
6772 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006773 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006774 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006775
6776 return exact ? lm1 : lm2;
6777}
6778
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006779void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006780{
Marcel Holtmann01394182006-07-03 10:02:46 +02006781 struct l2cap_conn *conn;
6782
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006783 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006784
Linus Torvalds1da177e2005-04-16 15:20:36 -07006785 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03006786 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006787 if (conn)
6788 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006789 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006790 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006791 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006792}
6793
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006794int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006795{
6796 struct l2cap_conn *conn = hcon->l2cap_data;
6797
6798 BT_DBG("hcon %p", hcon);
6799
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006800 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006801 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006802 return conn->disc_reason;
6803}
6804
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006805void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006806{
6807 BT_DBG("hcon %p reason %d", hcon, reason);
6808
Joe Perchese1750722011-06-29 18:18:29 -07006809 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006810}
6811
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006812static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006813{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006814 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006815 return;
6816
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006817 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006818 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006819 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006820 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006821 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006822 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006823 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006824 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006825 }
6826}
6827
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006828int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006829{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006830 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006831 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006832
Marcel Holtmann01394182006-07-03 10:02:46 +02006833 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006834 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006835
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006836 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006837
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006838 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306839 if (!status && encrypt)
6840 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006841 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006842 }
6843
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006844 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006845
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006846 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006847 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006848
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006849 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6850 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006851
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006852 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6853 l2cap_chan_unlock(chan);
6854 continue;
6855 }
6856
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006857 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006858 if (!status && encrypt) {
6859 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006860 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006861 }
6862
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006863 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006864 continue;
6865 }
6866
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006867 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006868 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006869 continue;
6870 }
6871
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006872 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006873 chan->state == BT_CONFIG)) {
Marcel Holtmannd97c8992013-10-14 02:53:54 -07006874 chan->ops->resume(chan);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006875 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006876 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006877 continue;
6878 }
6879
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006880 if (chan->state == BT_CONNECT) {
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02006881 if (!status)
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006882 l2cap_start_connection(chan);
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02006883 else
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006884 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006885 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006886 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006887 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006888
6889 if (!status) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07006890 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006891 res = L2CAP_CR_PEND;
6892 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006893 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006894 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02006895 l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006896 res = L2CAP_CR_SUCCESS;
6897 stat = L2CAP_CS_NO_INFO;
6898 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006899 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02006900 l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006901 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006902 res = L2CAP_CR_SEC_BLOCK;
6903 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006904 }
6905
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006906 rsp.scid = cpu_to_le16(chan->dcid);
6907 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006908 rsp.result = cpu_to_le16(res);
6909 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006910 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006911 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006912
6913 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6914 res == L2CAP_CR_SUCCESS) {
6915 char buf[128];
6916 set_bit(CONF_REQ_SENT, &chan->conf_state);
6917 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6918 L2CAP_CONF_REQ,
6919 l2cap_build_conf_req(chan, buf),
6920 buf);
6921 chan->num_conf_req++;
6922 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006923 }
6924
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006925 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006926 }
6927
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006928 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006929
Linus Torvalds1da177e2005-04-16 15:20:36 -07006930 return 0;
6931}
6932
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006933int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006934{
6935 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006936 struct l2cap_hdr *hdr;
6937 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006938
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006939 /* For AMP controller do not create l2cap conn */
6940 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6941 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006942
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006943 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03006944 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006945
6946 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006947 goto drop;
6948
6949 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6950
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006951 switch (flags) {
6952 case ACL_START:
6953 case ACL_START_NO_FLUSH:
6954 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006955 if (conn->rx_len) {
6956 BT_ERR("Unexpected start frame (len %d)", skb->len);
6957 kfree_skb(conn->rx_skb);
6958 conn->rx_skb = NULL;
6959 conn->rx_len = 0;
6960 l2cap_conn_unreliable(conn, ECOMM);
6961 }
6962
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006963 /* Start fragment always begin with Basic L2CAP header */
6964 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006965 BT_ERR("Frame is too short (len %d)", skb->len);
6966 l2cap_conn_unreliable(conn, ECOMM);
6967 goto drop;
6968 }
6969
6970 hdr = (struct l2cap_hdr *) skb->data;
6971 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6972
6973 if (len == skb->len) {
6974 /* Complete frame received */
6975 l2cap_recv_frame(conn, skb);
6976 return 0;
6977 }
6978
6979 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6980
6981 if (skb->len > len) {
6982 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006983 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006984 l2cap_conn_unreliable(conn, ECOMM);
6985 goto drop;
6986 }
6987
6988 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006989 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006990 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006991 goto drop;
6992
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006993 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006994 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006995 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006996 break;
6997
6998 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006999 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
7000
7001 if (!conn->rx_len) {
7002 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
7003 l2cap_conn_unreliable(conn, ECOMM);
7004 goto drop;
7005 }
7006
7007 if (skb->len > conn->rx_len) {
7008 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01007009 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007010 kfree_skb(conn->rx_skb);
7011 conn->rx_skb = NULL;
7012 conn->rx_len = 0;
7013 l2cap_conn_unreliable(conn, ECOMM);
7014 goto drop;
7015 }
7016
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03007017 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01007018 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007019 conn->rx_len -= skb->len;
7020
7021 if (!conn->rx_len) {
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02007022 /* Complete frame received. l2cap_recv_frame
7023 * takes ownership of the skb so set the global
7024 * rx_skb pointer to NULL first.
7025 */
7026 struct sk_buff *rx_skb = conn->rx_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007027 conn->rx_skb = NULL;
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02007028 l2cap_recv_frame(conn, rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007029 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007030 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007031 }
7032
7033drop:
7034 kfree_skb(skb);
7035 return 0;
7036}
7037
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007038static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007039{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007040 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007041
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02007042 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007043
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007044 list_for_each_entry(c, &chan_list, global_l) {
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03007045 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 -07007046 &c->src, &c->dst,
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03007047 c->state, __le16_to_cpu(c->psm),
7048 c->scid, c->dcid, c->imtu, c->omtu,
7049 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02007050 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007051
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02007052 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08007053
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007054 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007055}
7056
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007057static int l2cap_debugfs_open(struct inode *inode, struct file *file)
7058{
7059 return single_open(file, l2cap_debugfs_show, inode->i_private);
7060}
7061
7062static const struct file_operations l2cap_debugfs_fops = {
7063 .open = l2cap_debugfs_open,
7064 .read = seq_read,
7065 .llseek = seq_lseek,
7066 .release = single_release,
7067};
7068
7069static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007070
Gustavo F. Padovan64274512011-02-07 20:08:52 -02007071int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007072{
7073 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08007074
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007075 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07007076 if (err < 0)
7077 return err;
7078
Marcel Holtmann1120e4b2013-10-17 17:24:16 -07007079 if (IS_ERR_OR_NULL(bt_debugfs))
7080 return 0;
7081
7082 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
7083 NULL, &l2cap_debugfs_fops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007084
Linus Torvalds1da177e2005-04-16 15:20:36 -07007085 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007086}
7087
Gustavo F. Padovan64274512011-02-07 20:08:52 -02007088void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007089{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007090 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007091 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07007092}
7093
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03007094module_param(disable_ertm, bool, 0644);
7095MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");