blob: eafcdf65718bfbf9f0407da50916020ed6e1c96b [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
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300620void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300621{
622 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300623
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700624 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300625
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300626 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300627 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100628 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300629 break;
630
631 case BT_CONNECTED:
632 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300633 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100634 conn->hcon->type == ACL_LINK) {
Gustavo Padovan8d836d72013-10-15 19:24:47 -0300635 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200636 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300637 } else
638 l2cap_chan_del(chan, reason);
639 break;
640
641 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300642 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100643 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300644 struct l2cap_conn_rsp rsp;
645 __u16 result;
646
Marcel Holtmannbdc25782013-10-14 02:45:34 -0700647 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300648 result = L2CAP_CR_SEC_BLOCK;
649 else
650 result = L2CAP_CR_BAD_PSM;
Marcel Holtmannbdc25782013-10-14 02:45:34 -0700651
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300652 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300653
654 rsp.scid = cpu_to_le16(chan->dcid);
655 rsp.dcid = cpu_to_le16(chan->scid);
656 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300657 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300658 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100659 sizeof(rsp), &rsp);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300660 }
661
662 l2cap_chan_del(chan, reason);
663 break;
664
665 case BT_CONNECT:
666 case BT_DISCONN:
667 l2cap_chan_del(chan, reason);
668 break;
669
670 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100671 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300672 break;
673 }
674}
675
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300676static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530677{
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700678 switch (chan->chan_type) {
679 case L2CAP_CHAN_RAW:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300680 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530681 case BT_SECURITY_HIGH:
682 return HCI_AT_DEDICATED_BONDING_MITM;
683 case BT_SECURITY_MEDIUM:
684 return HCI_AT_DEDICATED_BONDING;
685 default:
686 return HCI_AT_NO_BONDING;
687 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700688 break;
Marcel Holtmann3124b842013-10-12 07:19:32 -0700689 case L2CAP_CHAN_CONN_LESS:
690 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_3DSP)) {
691 if (chan->sec_level == BT_SECURITY_LOW)
692 chan->sec_level = BT_SECURITY_SDP;
693 }
694 if (chan->sec_level == BT_SECURITY_HIGH)
695 return HCI_AT_NO_BONDING_MITM;
696 else
697 return HCI_AT_NO_BONDING;
698 break;
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700699 case L2CAP_CHAN_CONN_ORIENTED:
700 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
701 if (chan->sec_level == BT_SECURITY_LOW)
702 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530703
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700704 if (chan->sec_level == BT_SECURITY_HIGH)
705 return HCI_AT_NO_BONDING_MITM;
706 else
707 return HCI_AT_NO_BONDING;
708 }
709 /* fall through */
710 default:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300711 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530712 case BT_SECURITY_HIGH:
713 return HCI_AT_GENERAL_BONDING_MITM;
714 case BT_SECURITY_MEDIUM:
715 return HCI_AT_GENERAL_BONDING;
716 default:
717 return HCI_AT_NO_BONDING;
718 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700719 break;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530720 }
721}
722
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200723/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200724int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200725{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300726 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100727 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200728
Johan Hedberga17de2f2013-05-14 13:25:37 +0300729 if (conn->hcon->type == LE_LINK)
730 return smp_conn_security(conn->hcon, chan->sec_level);
731
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300732 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100733
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300734 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200735}
736
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200737static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200738{
739 u8 id;
740
741 /* Get next available identificator.
742 * 1 - 128 are used by kernel.
743 * 129 - 199 are reserved.
744 * 200 - 254 are used by utilities like l2ping, etc.
745 */
746
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200747 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200748
749 if (++conn->tx_ident > 128)
750 conn->tx_ident = 1;
751
752 id = conn->tx_ident;
753
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200754 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200755
756 return id;
757}
758
Gustavo Padovan2d792812012-10-06 10:07:01 +0100759static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
760 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200761{
762 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200763 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200764
765 BT_DBG("code 0x%2.2x", code);
766
767 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300768 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200769
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200770 if (lmp_no_flush_capable(conn->hcon->hdev))
771 flags = ACL_START_NO_FLUSH;
772 else
773 flags = ACL_START;
774
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700775 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200776 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700777
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200778 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200779}
780
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700781static bool __chan_is_moving(struct l2cap_chan *chan)
782{
783 return chan->move_state != L2CAP_MOVE_STABLE &&
784 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
785}
786
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200787static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
788{
789 struct hci_conn *hcon = chan->conn->hcon;
790 u16 flags;
791
792 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100793 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200794
Mat Martineaud5f8a752012-10-23 15:24:18 -0700795 if (chan->hs_hcon && !__chan_is_moving(chan)) {
796 if (chan->hs_hchan)
797 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
798 else
799 kfree_skb(skb);
800
801 return;
802 }
803
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200804 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100805 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200806 flags = ACL_START_NO_FLUSH;
807 else
808 flags = ACL_START;
809
810 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
811 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812}
813
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700814static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
815{
816 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
817 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
818
819 if (enh & L2CAP_CTRL_FRAME_TYPE) {
820 /* S-Frame */
821 control->sframe = 1;
822 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
823 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
824
825 control->sar = 0;
826 control->txseq = 0;
827 } else {
828 /* I-Frame */
829 control->sframe = 0;
830 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
831 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
832
833 control->poll = 0;
834 control->super = 0;
835 }
836}
837
838static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
839{
840 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
841 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
842
843 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
844 /* S-Frame */
845 control->sframe = 1;
846 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
847 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
848
849 control->sar = 0;
850 control->txseq = 0;
851 } else {
852 /* I-Frame */
853 control->sframe = 0;
854 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
855 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
856
857 control->poll = 0;
858 control->super = 0;
859 }
860}
861
862static inline void __unpack_control(struct l2cap_chan *chan,
863 struct sk_buff *skb)
864{
865 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
866 __unpack_extended_control(get_unaligned_le32(skb->data),
867 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700868 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700869 } else {
870 __unpack_enhanced_control(get_unaligned_le16(skb->data),
871 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700872 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700873 }
874}
875
876static u32 __pack_extended_control(struct l2cap_ctrl *control)
877{
878 u32 packed;
879
880 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
881 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
882
883 if (control->sframe) {
884 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
885 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
886 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
887 } else {
888 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
889 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
890 }
891
892 return packed;
893}
894
895static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
896{
897 u16 packed;
898
899 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
900 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
901
902 if (control->sframe) {
903 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
904 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
905 packed |= L2CAP_CTRL_FRAME_TYPE;
906 } else {
907 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
908 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
909 }
910
911 return packed;
912}
913
914static inline void __pack_control(struct l2cap_chan *chan,
915 struct l2cap_ctrl *control,
916 struct sk_buff *skb)
917{
918 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
919 put_unaligned_le32(__pack_extended_control(control),
920 skb->data + L2CAP_HDR_SIZE);
921 } else {
922 put_unaligned_le16(__pack_enhanced_control(control),
923 skb->data + L2CAP_HDR_SIZE);
924 }
925}
926
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300927static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
928{
929 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
930 return L2CAP_EXT_HDR_SIZE;
931 else
932 return L2CAP_ENH_HDR_SIZE;
933}
934
Mat Martineaua67d7f62012-05-17 20:53:35 -0700935static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
936 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300937{
938 struct sk_buff *skb;
939 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300940 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300941
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300942 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300943 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300944
Mat Martineaua67d7f62012-05-17 20:53:35 -0700945 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300946
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300947 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700948 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300949
950 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300951 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300952 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300953
Mat Martineaua67d7f62012-05-17 20:53:35 -0700954 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
955 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
956 else
957 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300958
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300959 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700960 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300961 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300962 }
963
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200964 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700965 return skb;
966}
967
968static void l2cap_send_sframe(struct l2cap_chan *chan,
969 struct l2cap_ctrl *control)
970{
971 struct sk_buff *skb;
972 u32 control_field;
973
974 BT_DBG("chan %p, control %p", chan, control);
975
976 if (!control->sframe)
977 return;
978
Mat Martineaub99e13a2012-10-23 15:24:19 -0700979 if (__chan_is_moving(chan))
980 return;
981
Mat Martineaua67d7f62012-05-17 20:53:35 -0700982 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
983 !control->poll)
984 control->final = 1;
985
986 if (control->super == L2CAP_SUPER_RR)
987 clear_bit(CONN_RNR_SENT, &chan->conn_state);
988 else if (control->super == L2CAP_SUPER_RNR)
989 set_bit(CONN_RNR_SENT, &chan->conn_state);
990
991 if (control->super != L2CAP_SUPER_SREJ) {
992 chan->last_acked_seq = control->reqseq;
993 __clear_ack_timer(chan);
994 }
995
996 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
997 control->final, control->poll, control->super);
998
999 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1000 control_field = __pack_extended_control(control);
1001 else
1002 control_field = __pack_enhanced_control(control);
1003
1004 skb = l2cap_create_sframe_pdu(chan, control_field);
1005 if (!IS_ERR(skb))
1006 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001007}
1008
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001009static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001010{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001011 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001012
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001013 BT_DBG("chan %p, poll %d", chan, poll);
1014
1015 memset(&control, 0, sizeof(control));
1016 control.sframe = 1;
1017 control.poll = poll;
1018
1019 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
1020 control.super = L2CAP_SUPER_RNR;
1021 else
1022 control.super = L2CAP_SUPER_RR;
1023
1024 control.reqseq = chan->buffer_seq;
1025 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001026}
1027
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001028static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001029{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001030 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001031}
1032
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001033static bool __amp_capable(struct l2cap_chan *chan)
1034{
1035 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001036 struct hci_dev *hdev;
1037 bool amp_available = false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001038
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001039 if (!conn->hs_enabled)
1040 return false;
1041
1042 if (!(conn->fixed_chan_mask & L2CAP_FC_A2MP))
1043 return false;
1044
1045 read_lock(&hci_dev_list_lock);
1046 list_for_each_entry(hdev, &hci_dev_list, list) {
1047 if (hdev->amp_type != AMP_TYPE_BREDR &&
1048 test_bit(HCI_UP, &hdev->flags)) {
1049 amp_available = true;
1050 break;
1051 }
1052 }
1053 read_unlock(&hci_dev_list_lock);
1054
1055 if (chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED)
1056 return amp_available;
Marcel Holtmann848566b2013-10-01 22:59:22 -07001057
1058 return false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001059}
1060
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001061static bool l2cap_check_efs(struct l2cap_chan *chan)
1062{
1063 /* Check EFS parameters */
1064 return true;
1065}
1066
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001067void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001068{
1069 struct l2cap_conn *conn = chan->conn;
1070 struct l2cap_conn_req req;
1071
1072 req.scid = cpu_to_le16(chan->scid);
1073 req.psm = chan->psm;
1074
1075 chan->ident = l2cap_get_ident(conn);
1076
1077 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1078
1079 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1080}
1081
Mat Martineau8eb200b2012-10-23 15:24:17 -07001082static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1083{
1084 struct l2cap_create_chan_req req;
1085 req.scid = cpu_to_le16(chan->scid);
1086 req.psm = chan->psm;
1087 req.amp_id = amp_id;
1088
1089 chan->ident = l2cap_get_ident(chan->conn);
1090
1091 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1092 sizeof(req), &req);
1093}
1094
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001095static void l2cap_move_setup(struct l2cap_chan *chan)
1096{
1097 struct sk_buff *skb;
1098
1099 BT_DBG("chan %p", chan);
1100
1101 if (chan->mode != L2CAP_MODE_ERTM)
1102 return;
1103
1104 __clear_retrans_timer(chan);
1105 __clear_monitor_timer(chan);
1106 __clear_ack_timer(chan);
1107
1108 chan->retry_count = 0;
1109 skb_queue_walk(&chan->tx_q, skb) {
1110 if (bt_cb(skb)->control.retries)
1111 bt_cb(skb)->control.retries = 1;
1112 else
1113 break;
1114 }
1115
1116 chan->expected_tx_seq = chan->buffer_seq;
1117
1118 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1119 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1120 l2cap_seq_list_clear(&chan->retrans_list);
1121 l2cap_seq_list_clear(&chan->srej_list);
1122 skb_queue_purge(&chan->srej_q);
1123
1124 chan->tx_state = L2CAP_TX_STATE_XMIT;
1125 chan->rx_state = L2CAP_RX_STATE_MOVE;
1126
1127 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1128}
1129
Mat Martineau5f3847a2012-10-23 15:24:12 -07001130static void l2cap_move_done(struct l2cap_chan *chan)
1131{
1132 u8 move_role = chan->move_role;
1133 BT_DBG("chan %p", chan);
1134
1135 chan->move_state = L2CAP_MOVE_STABLE;
1136 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1137
1138 if (chan->mode != L2CAP_MODE_ERTM)
1139 return;
1140
1141 switch (move_role) {
1142 case L2CAP_MOVE_ROLE_INITIATOR:
1143 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1144 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1145 break;
1146 case L2CAP_MOVE_ROLE_RESPONDER:
1147 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1148 break;
1149 }
1150}
1151
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001152static void l2cap_chan_ready(struct l2cap_chan *chan)
1153{
Mat Martineau28270112012-05-17 21:14:09 -07001154 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001155 chan->conf_state = 0;
1156 __clear_chan_timer(chan);
1157
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001158 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001159
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001160 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001161}
1162
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001163static void l2cap_start_connection(struct l2cap_chan *chan)
1164{
1165 if (__amp_capable(chan)) {
1166 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1167 a2mp_discover_amp(chan);
1168 } else {
1169 l2cap_send_conn_req(chan);
1170 }
1171}
1172
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001173static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001174{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001175 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001176
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001177 if (conn->hcon->type == LE_LINK) {
1178 l2cap_chan_ready(chan);
1179 return;
1180 }
1181
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001182 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001183 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1184 return;
1185
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001186 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001187 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001188 l2cap_start_connection(chan);
1189 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001190 } else {
1191 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001192 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001193
1194 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1195 conn->info_ident = l2cap_get_ident(conn);
1196
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001197 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001198
Gustavo Padovan2d792812012-10-06 10:07:01 +01001199 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1200 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001201 }
1202}
1203
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001204static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1205{
1206 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001207 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001208 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1209
1210 switch (mode) {
1211 case L2CAP_MODE_ERTM:
1212 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1213 case L2CAP_MODE_STREAMING:
1214 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1215 default:
1216 return 0x00;
1217 }
1218}
1219
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001220static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001221{
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001222 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001223 struct l2cap_disconn_req req;
1224
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001225 if (!conn)
1226 return;
1227
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001228 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001229 __clear_retrans_timer(chan);
1230 __clear_monitor_timer(chan);
1231 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001232 }
1233
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001234 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001235 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001236 return;
1237 }
1238
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001239 req.dcid = cpu_to_le16(chan->dcid);
1240 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001241 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1242 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001243
Gustavo Padovanf8e73012013-10-15 19:24:46 -03001244 l2cap_state_change_and_error(chan, BT_DISCONN, err);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001245}
1246
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001248static void l2cap_conn_start(struct l2cap_conn *conn)
1249{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001250 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001251
1252 BT_DBG("conn %p", conn);
1253
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001254 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001255
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001256 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001257 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001258
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001259 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001260 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001261 continue;
1262 }
1263
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001264 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001265 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001266 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001267 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001268 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001269 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001270
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001271 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001272 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001273 &chan->conf_state)) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001274 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001275 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001276 continue;
1277 }
1278
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001279 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001280
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001281 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001282 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001283 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001284 rsp.scid = cpu_to_le16(chan->dcid);
1285 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001286
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001287 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07001288 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001289 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1290 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001291 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001292
1293 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02001294 l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001295 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1296 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001297 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001298 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001299 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1300 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001301 }
1302
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001303 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001304 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001305
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001306 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001307 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001308 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001309 continue;
1310 }
1311
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001312 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001313 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001314 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001315 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001316 }
1317
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001318 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001319 }
1320
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001321 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001322}
1323
Ido Yarivc2287682012-04-20 15:46:07 -03001324/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001325 * Returns closest match, locked.
1326 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001327static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001328 bdaddr_t *src,
1329 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001330{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001331 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001332
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001333 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001334
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001335 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001336 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001337 continue;
1338
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001339 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001340 int src_match, dst_match;
1341 int src_any, dst_any;
1342
Ville Tervob62f3282011-02-10 22:38:50 -03001343 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001344 src_match = !bacmp(&c->src, src);
1345 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001346 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001347 read_unlock(&chan_list_lock);
1348 return c;
1349 }
Ville Tervob62f3282011-02-10 22:38:50 -03001350
1351 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001352 src_any = !bacmp(&c->src, BDADDR_ANY);
1353 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001354 if ((src_match && dst_any) || (src_any && dst_match) ||
1355 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001356 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001357 }
1358 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001359
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001360 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001361
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001362 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001363}
1364
1365static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1366{
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001367 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001368 struct l2cap_chan *chan, *pchan;
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001369 u8 dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001370
1371 BT_DBG("");
1372
1373 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001374 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001375 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001376 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001377 return;
1378
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001379 /* Client ATT sockets should override the server one */
1380 if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
1381 return;
1382
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001383 dst_type = bdaddr_type(hcon, hcon->dst_type);
1384
1385 /* If device is blocked, do not create a channel for it */
1386 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, dst_type))
1387 return;
1388
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001389 l2cap_chan_lock(pchan);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001390
Gustavo Padovan80b98022012-05-27 22:27:51 -03001391 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001392 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001393 goto clean;
1394
Johan Hedberg9f22398c2013-04-29 19:35:38 +03001395 chan->dcid = L2CAP_CID_ATT;
1396
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001397 bacpy(&chan->src, &hcon->src);
1398 bacpy(&chan->dst, &hcon->dst);
1399 chan->src_type = bdaddr_type(hcon, hcon->src_type);
1400 chan->dst_type = dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001401
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001402 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001403
Ville Tervob62f3282011-02-10 22:38:50 -03001404clean:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001405 l2cap_chan_unlock(pchan);
Ville Tervob62f3282011-02-10 22:38:50 -03001406}
1407
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001408static void l2cap_conn_ready(struct l2cap_conn *conn)
1409{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001410 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001411 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001412
1413 BT_DBG("conn %p", conn);
1414
Johan Hedbergd8729922013-04-29 19:35:39 +03001415 /* For outgoing pairing which doesn't necessarily have an
1416 * associated socket (e.g. mgmt_pair_device).
1417 */
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001418 if (hcon->out && hcon->type == LE_LINK)
1419 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001420
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001421 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001422
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001423 if (hcon->type == LE_LINK)
1424 l2cap_le_conn_ready(conn);
1425
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001426 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001427
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001428 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001429
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001430 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1431 l2cap_chan_unlock(chan);
1432 continue;
1433 }
1434
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001435 if (hcon->type == LE_LINK) {
1436 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001437 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001438
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001439 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo Padovan74e75742013-10-15 19:24:51 -03001440 l2cap_chan_ready(chan);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001441
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001442 } else if (chan->state == BT_CONNECT) {
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001443 l2cap_do_start(chan);
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001444 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001445
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001446 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001447 }
1448
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001449 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001450}
1451
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001452/* Notify sockets that we cannot guaranty reliability anymore */
1453static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1454{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001455 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001456
1457 BT_DBG("conn %p", conn);
1458
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001459 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001460
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001461 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001462 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001463 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001464 }
1465
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001466 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001467}
1468
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001469static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001470{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001471 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001472 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001473
Marcel Holtmann984947d2009-02-06 23:35:19 +01001474 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001475 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001476
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001477 l2cap_conn_start(conn);
1478}
1479
David Herrmann2c8e1412013-04-06 20:28:45 +02001480/*
1481 * l2cap_user
1482 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1483 * callback is called during registration. The ->remove callback is called
1484 * during unregistration.
1485 * An l2cap_user object can either be explicitly unregistered or when the
1486 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1487 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1488 * External modules must own a reference to the l2cap_conn object if they intend
1489 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1490 * any time if they don't.
1491 */
1492
1493int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1494{
1495 struct hci_dev *hdev = conn->hcon->hdev;
1496 int ret;
1497
1498 /* We need to check whether l2cap_conn is registered. If it is not, we
1499 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1500 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1501 * relies on the parent hci_conn object to be locked. This itself relies
1502 * on the hci_dev object to be locked. So we must lock the hci device
1503 * here, too. */
1504
1505 hci_dev_lock(hdev);
1506
1507 if (user->list.next || user->list.prev) {
1508 ret = -EINVAL;
1509 goto out_unlock;
1510 }
1511
1512 /* conn->hchan is NULL after l2cap_conn_del() was called */
1513 if (!conn->hchan) {
1514 ret = -ENODEV;
1515 goto out_unlock;
1516 }
1517
1518 ret = user->probe(conn, user);
1519 if (ret)
1520 goto out_unlock;
1521
1522 list_add(&user->list, &conn->users);
1523 ret = 0;
1524
1525out_unlock:
1526 hci_dev_unlock(hdev);
1527 return ret;
1528}
1529EXPORT_SYMBOL(l2cap_register_user);
1530
1531void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1532{
1533 struct hci_dev *hdev = conn->hcon->hdev;
1534
1535 hci_dev_lock(hdev);
1536
1537 if (!user->list.next || !user->list.prev)
1538 goto out_unlock;
1539
1540 list_del(&user->list);
1541 user->list.next = NULL;
1542 user->list.prev = NULL;
1543 user->remove(conn, user);
1544
1545out_unlock:
1546 hci_dev_unlock(hdev);
1547}
1548EXPORT_SYMBOL(l2cap_unregister_user);
1549
1550static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1551{
1552 struct l2cap_user *user;
1553
1554 while (!list_empty(&conn->users)) {
1555 user = list_first_entry(&conn->users, struct l2cap_user, list);
1556 list_del(&user->list);
1557 user->list.next = NULL;
1558 user->list.prev = NULL;
1559 user->remove(conn, user);
1560 }
1561}
1562
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001563static void l2cap_conn_del(struct hci_conn *hcon, int err)
1564{
1565 struct l2cap_conn *conn = hcon->l2cap_data;
1566 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001567
1568 if (!conn)
1569 return;
1570
1571 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1572
1573 kfree_skb(conn->rx_skb);
1574
David Herrmann2c8e1412013-04-06 20:28:45 +02001575 l2cap_unregister_all_users(conn);
1576
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001577 mutex_lock(&conn->chan_lock);
1578
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001579 /* Kill channels */
1580 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001581 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001582 l2cap_chan_lock(chan);
1583
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001584 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001585
1586 l2cap_chan_unlock(chan);
1587
Gustavo Padovan80b98022012-05-27 22:27:51 -03001588 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001589 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001590 }
1591
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001592 mutex_unlock(&conn->chan_lock);
1593
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001594 hci_chan_del(conn->hchan);
1595
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001596 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001597 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001598
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001599 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001600 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001601 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001602 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001603
1604 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001605 conn->hchan = NULL;
1606 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001607}
1608
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001609static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001610{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001611 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001612 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001613
Johan Hedbergd06cc412012-06-06 18:44:11 +08001614 BT_DBG("conn %p", conn);
1615
1616 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1617 smp_chan_destroy(conn);
1618 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1619 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001620}
1621
Claudio Takahasibaf43252013-04-11 13:55:50 -03001622static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623{
Marcel Holtmann01394182006-07-03 10:02:46 +02001624 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001625 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626
Claudio Takahasibaf43252013-04-11 13:55:50 -03001627 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001628 return conn;
1629
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001630 hchan = hci_chan_create(hcon);
1631 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001632 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001633
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001634 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001635 if (!conn) {
1636 hci_chan_del(hchan);
1637 return NULL;
1638 }
1639
David Herrmann9c903e32013-04-06 20:28:44 +02001640 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641 hcon->l2cap_data = conn;
1642 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001643 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001644 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001645
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001646 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001647
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001648 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001649 case LE_LINK:
1650 if (hcon->hdev->le_mtu) {
1651 conn->mtu = hcon->hdev->le_mtu;
1652 break;
1653 }
1654 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001655 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001656 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001657 break;
1658 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001659
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001660 conn->feat_mask = 0;
1661
Marcel Holtmann848566b2013-10-01 22:59:22 -07001662 if (hcon->type == ACL_LINK)
1663 conn->hs_enabled = test_bit(HCI_HS_ENABLED,
1664 &hcon->hdev->dev_flags);
1665
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001667 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001668
1669 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001670 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001672 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001673 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001674 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001675 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001676
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001677 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001678
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 return conn;
1680}
1681
David Herrmann9c903e32013-04-06 20:28:44 +02001682static void l2cap_conn_free(struct kref *ref)
1683{
1684 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1685
1686 hci_conn_put(conn->hcon);
1687 kfree(conn);
1688}
1689
1690void l2cap_conn_get(struct l2cap_conn *conn)
1691{
1692 kref_get(&conn->ref);
1693}
1694EXPORT_SYMBOL(l2cap_conn_get);
1695
1696void l2cap_conn_put(struct l2cap_conn *conn)
1697{
1698 kref_put(&conn->ref, l2cap_conn_free);
1699}
1700EXPORT_SYMBOL(l2cap_conn_put);
1701
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703
Ido Yarivc2287682012-04-20 15:46:07 -03001704/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705 * Returns closest match.
1706 */
Ido Yarivc2287682012-04-20 15:46:07 -03001707static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1708 bdaddr_t *src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001709 bdaddr_t *dst,
1710 u8 link_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001712 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001714 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001715
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001716 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001717 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 continue;
1719
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001720 if (link_type == ACL_LINK && c->src_type != BDADDR_BREDR)
1721 continue;
1722
1723 if (link_type == LE_LINK && c->src_type == BDADDR_BREDR)
1724 continue;
1725
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001726 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001727 int src_match, dst_match;
1728 int src_any, dst_any;
1729
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001731 src_match = !bacmp(&c->src, src);
1732 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001733 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001734 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001735 return c;
1736 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737
1738 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001739 src_any = !bacmp(&c->src, BDADDR_ANY);
1740 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001741 if ((src_match && dst_any) || (src_any && dst_match) ||
1742 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001743 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744 }
1745 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001747 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001748
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001749 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750}
1751
Andre Guedes8e9f9892012-04-24 21:02:55 -03001752int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1753 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 struct l2cap_conn *conn;
1756 struct hci_conn *hcon;
1757 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001758 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001759 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001761 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301762 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001764 hdev = hci_get_route(dst, &chan->src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001765 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766 return -EHOSTUNREACH;
1767
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001768 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001770 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001771
1772 /* PSM must be odd and lsb of upper byte must be 0 */
1773 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001774 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001775 err = -EINVAL;
1776 goto done;
1777 }
1778
1779 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1780 err = -EINVAL;
1781 goto done;
1782 }
1783
1784 switch (chan->mode) {
1785 case L2CAP_MODE_BASIC:
1786 break;
1787 case L2CAP_MODE_ERTM:
1788 case L2CAP_MODE_STREAMING:
1789 if (!disable_ertm)
1790 break;
1791 /* fall through */
1792 default:
1793 err = -ENOTSUPP;
1794 goto done;
1795 }
1796
Gustavo Padovan0797e012012-05-27 22:27:54 -03001797 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001798 case BT_CONNECT:
1799 case BT_CONNECT2:
1800 case BT_CONFIG:
1801 /* Already connecting */
1802 err = 0;
1803 goto done;
1804
1805 case BT_CONNECTED:
1806 /* Already connected */
1807 err = -EISCONN;
1808 goto done;
1809
1810 case BT_OPEN:
1811 case BT_BOUND:
1812 /* Can connect */
1813 break;
1814
1815 default:
1816 err = -EBADFD;
1817 goto done;
1818 }
1819
1820 /* Set destination address and psm */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001821 bacpy(&chan->dst, dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001822 chan->dst_type = dst_type;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001823
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001824 chan->psm = psm;
1825 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001827 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001828
Johan Hedbergf224ca52013-04-29 19:35:36 +03001829 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001830 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001831 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001832 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001833 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001834 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001835
Ville Tervo30e76272011-02-22 16:10:53 -03001836 if (IS_ERR(hcon)) {
1837 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001839 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840
Claudio Takahasibaf43252013-04-11 13:55:50 -03001841 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001843 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001844 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845 goto done;
1846 }
1847
Johan Hedberg141d5702013-04-29 19:35:37 +03001848 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1849 hci_conn_drop(hcon);
1850 err = -EBUSY;
1851 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001852 }
1853
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854 /* Update source addr of the socket */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001855 bacpy(&chan->src, &hcon->src);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001856 chan->src_type = bdaddr_type(hcon, hcon->src_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001858 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001859 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001860 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001861
Johan Hedberg5ee98912013-04-29 19:35:43 +03001862 /* l2cap_chan_add takes its own ref so we can drop this one */
1863 hci_conn_drop(hcon);
1864
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001865 l2cap_state_change(chan, BT_CONNECT);
Gustavo Padovan8d836d72013-10-15 19:24:47 -03001866 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867
1868 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001869 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001870 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001871 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001872 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001873 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001874 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001875 }
1876
Ville Tervo30e76272011-02-22 16:10:53 -03001877 err = 0;
1878
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001880 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001881 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882 hci_dev_put(hdev);
1883 return err;
1884}
1885
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001886static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001887{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001888 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001889 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001890
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001891 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001892
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001893 l2cap_chan_lock(chan);
1894
Mat Martineau80909e02012-05-17 20:53:50 -07001895 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001896 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001897 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001898 return;
1899 }
1900
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001901 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001902
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001903 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001904 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001905}
1906
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001907static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001908{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001909 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001910 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001911
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001912 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001913
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001914 l2cap_chan_lock(chan);
1915
Mat Martineau80909e02012-05-17 20:53:50 -07001916 if (!chan->conn) {
1917 l2cap_chan_unlock(chan);
1918 l2cap_chan_put(chan);
1919 return;
1920 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001921
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001922 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001923 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001924 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001925}
1926
Gustavo Padovand6603662012-05-21 13:58:22 -03001927static void l2cap_streaming_send(struct l2cap_chan *chan,
1928 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001929{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001930 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001931 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001932
Mat Martineau37339372012-05-17 20:53:33 -07001933 BT_DBG("chan %p, skbs %p", chan, skbs);
1934
Mat Martineaub99e13a2012-10-23 15:24:19 -07001935 if (__chan_is_moving(chan))
1936 return;
1937
Mat Martineau37339372012-05-17 20:53:33 -07001938 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1939
1940 while (!skb_queue_empty(&chan->tx_q)) {
1941
1942 skb = skb_dequeue(&chan->tx_q);
1943
1944 bt_cb(skb)->control.retries = 1;
1945 control = &bt_cb(skb)->control;
1946
1947 control->reqseq = 0;
1948 control->txseq = chan->next_tx_seq;
1949
1950 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001951
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001952 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001953 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1954 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001955 }
1956
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001957 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001958
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001959 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001960
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001961 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001962 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001963 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001964}
1965
Szymon Janc67c9e842011-07-28 16:24:33 +02001966static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001967{
1968 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001969 struct l2cap_ctrl *control;
1970 int sent = 0;
1971
1972 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001973
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001974 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001975 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001976
Mat Martineau94122bb2012-05-02 09:42:02 -07001977 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1978 return 0;
1979
Mat Martineaub99e13a2012-10-23 15:24:19 -07001980 if (__chan_is_moving(chan))
1981 return 0;
1982
Mat Martineau18a48e72012-05-17 20:53:34 -07001983 while (chan->tx_send_head &&
1984 chan->unacked_frames < chan->remote_tx_win &&
1985 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001986
Mat Martineau18a48e72012-05-17 20:53:34 -07001987 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001988
Mat Martineau18a48e72012-05-17 20:53:34 -07001989 bt_cb(skb)->control.retries = 1;
1990 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001991
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001992 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001993 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001994
Mat Martineau18a48e72012-05-17 20:53:34 -07001995 control->reqseq = chan->buffer_seq;
1996 chan->last_acked_seq = chan->buffer_seq;
1997 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001998
Mat Martineau18a48e72012-05-17 20:53:34 -07001999 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002000
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002001 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07002002 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2003 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002004 }
2005
Mat Martineau18a48e72012-05-17 20:53:34 -07002006 /* Clone after data has been modified. Data is assumed to be
2007 read-only (for locking purposes) on cloned sk_buffs.
2008 */
2009 tx_skb = skb_clone(skb, GFP_KERNEL);
2010
2011 if (!tx_skb)
2012 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002013
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002014 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002015
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002016 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002017 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002018 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002019 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002020
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002021 if (skb_queue_is_last(&chan->tx_q, skb))
2022 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002023 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002024 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002025
2026 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002027 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002028 }
2029
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002030 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2031 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002032
2033 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002034}
2035
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002036static void l2cap_ertm_resend(struct l2cap_chan *chan)
2037{
2038 struct l2cap_ctrl control;
2039 struct sk_buff *skb;
2040 struct sk_buff *tx_skb;
2041 u16 seq;
2042
2043 BT_DBG("chan %p", chan);
2044
2045 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2046 return;
2047
Mat Martineaub99e13a2012-10-23 15:24:19 -07002048 if (__chan_is_moving(chan))
2049 return;
2050
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002051 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2052 seq = l2cap_seq_list_pop(&chan->retrans_list);
2053
2054 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2055 if (!skb) {
2056 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002057 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002058 continue;
2059 }
2060
2061 bt_cb(skb)->control.retries++;
2062 control = bt_cb(skb)->control;
2063
2064 if (chan->max_tx != 0 &&
2065 bt_cb(skb)->control.retries > chan->max_tx) {
2066 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002067 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002068 l2cap_seq_list_clear(&chan->retrans_list);
2069 break;
2070 }
2071
2072 control.reqseq = chan->buffer_seq;
2073 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2074 control.final = 1;
2075 else
2076 control.final = 0;
2077
2078 if (skb_cloned(skb)) {
2079 /* Cloned sk_buffs are read-only, so we need a
2080 * writeable copy
2081 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002082 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002083 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002084 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002085 }
2086
2087 if (!tx_skb) {
2088 l2cap_seq_list_clear(&chan->retrans_list);
2089 break;
2090 }
2091
2092 /* Update skb contents */
2093 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2094 put_unaligned_le32(__pack_extended_control(&control),
2095 tx_skb->data + L2CAP_HDR_SIZE);
2096 } else {
2097 put_unaligned_le16(__pack_enhanced_control(&control),
2098 tx_skb->data + L2CAP_HDR_SIZE);
2099 }
2100
2101 if (chan->fcs == L2CAP_FCS_CRC16) {
2102 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2103 put_unaligned_le16(fcs, skb_put(tx_skb,
2104 L2CAP_FCS_SIZE));
2105 }
2106
2107 l2cap_do_send(chan, tx_skb);
2108
2109 BT_DBG("Resent txseq %d", control.txseq);
2110
2111 chan->last_acked_seq = chan->buffer_seq;
2112 }
2113}
2114
Mat Martineauf80842a2012-05-17 20:53:46 -07002115static void l2cap_retransmit(struct l2cap_chan *chan,
2116 struct l2cap_ctrl *control)
2117{
2118 BT_DBG("chan %p, control %p", chan, control);
2119
2120 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2121 l2cap_ertm_resend(chan);
2122}
2123
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002124static void l2cap_retransmit_all(struct l2cap_chan *chan,
2125 struct l2cap_ctrl *control)
2126{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002127 struct sk_buff *skb;
2128
2129 BT_DBG("chan %p, control %p", chan, control);
2130
2131 if (control->poll)
2132 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2133
2134 l2cap_seq_list_clear(&chan->retrans_list);
2135
2136 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2137 return;
2138
2139 if (chan->unacked_frames) {
2140 skb_queue_walk(&chan->tx_q, skb) {
2141 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002142 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002143 break;
2144 }
2145
2146 skb_queue_walk_from(&chan->tx_q, skb) {
2147 if (skb == chan->tx_send_head)
2148 break;
2149
2150 l2cap_seq_list_append(&chan->retrans_list,
2151 bt_cb(skb)->control.txseq);
2152 }
2153
2154 l2cap_ertm_resend(chan);
2155 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002156}
2157
Szymon Jancb17e73b2012-01-11 10:59:47 +01002158static void l2cap_send_ack(struct l2cap_chan *chan)
2159{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002160 struct l2cap_ctrl control;
2161 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2162 chan->last_acked_seq);
2163 int threshold;
2164
2165 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2166 chan, chan->last_acked_seq, chan->buffer_seq);
2167
2168 memset(&control, 0, sizeof(control));
2169 control.sframe = 1;
2170
2171 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2172 chan->rx_state == L2CAP_RX_STATE_RECV) {
2173 __clear_ack_timer(chan);
2174 control.super = L2CAP_SUPER_RNR;
2175 control.reqseq = chan->buffer_seq;
2176 l2cap_send_sframe(chan, &control);
2177 } else {
2178 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2179 l2cap_ertm_send(chan);
2180 /* If any i-frames were sent, they included an ack */
2181 if (chan->buffer_seq == chan->last_acked_seq)
2182 frames_to_ack = 0;
2183 }
2184
Mat Martineauc20f8e32012-07-10 05:47:07 -07002185 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002186 * Calculate without mul or div
2187 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002188 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002189 threshold += threshold << 1;
2190 threshold >>= 2;
2191
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002192 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002193 threshold);
2194
2195 if (frames_to_ack >= threshold) {
2196 __clear_ack_timer(chan);
2197 control.super = L2CAP_SUPER_RR;
2198 control.reqseq = chan->buffer_seq;
2199 l2cap_send_sframe(chan, &control);
2200 frames_to_ack = 0;
2201 }
2202
2203 if (frames_to_ack)
2204 __set_ack_timer(chan);
2205 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002206}
2207
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002208static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2209 struct msghdr *msg, int len,
2210 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002211{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002212 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002213 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002214 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002215
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002216 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002217 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002218
2219 sent += count;
2220 len -= count;
2221
2222 /* Continuation fragments (no L2CAP header) */
2223 frag = &skb_shinfo(skb)->frag_list;
2224 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002225 struct sk_buff *tmp;
2226
Linus Torvalds1da177e2005-04-16 15:20:36 -07002227 count = min_t(unsigned int, conn->mtu, len);
2228
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002229 tmp = chan->ops->alloc_skb(chan, count,
2230 msg->msg_flags & MSG_DONTWAIT);
2231 if (IS_ERR(tmp))
2232 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002233
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002234 *frag = tmp;
2235
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002236 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2237 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002238
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002239 (*frag)->priority = skb->priority;
2240
Linus Torvalds1da177e2005-04-16 15:20:36 -07002241 sent += count;
2242 len -= count;
2243
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002244 skb->len += (*frag)->len;
2245 skb->data_len += (*frag)->len;
2246
Linus Torvalds1da177e2005-04-16 15:20:36 -07002247 frag = &(*frag)->next;
2248 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249
2250 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002251}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002253static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002254 struct msghdr *msg, size_t len,
2255 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002256{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002257 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002258 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002259 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002260 struct l2cap_hdr *lh;
2261
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002262 BT_DBG("chan %p psm 0x%2.2x len %zu priority %u", chan,
2263 __le16_to_cpu(chan->psm), len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002264
2265 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002266
2267 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002268 msg->msg_flags & MSG_DONTWAIT);
2269 if (IS_ERR(skb))
2270 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002271
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002272 skb->priority = priority;
2273
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002274 /* Create L2CAP header */
2275 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002276 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002277 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002278 put_unaligned(chan->psm, (__le16 *) skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002279
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002280 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002281 if (unlikely(err < 0)) {
2282 kfree_skb(skb);
2283 return ERR_PTR(err);
2284 }
2285 return skb;
2286}
2287
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002288static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002289 struct msghdr *msg, size_t len,
2290 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002291{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002292 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002293 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002294 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002295 struct l2cap_hdr *lh;
2296
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002297 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002298
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002299 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002300
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002301 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002302 msg->msg_flags & MSG_DONTWAIT);
2303 if (IS_ERR(skb))
2304 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002305
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002306 skb->priority = priority;
2307
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002308 /* Create L2CAP header */
2309 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002310 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002311 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002312
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002313 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002314 if (unlikely(err < 0)) {
2315 kfree_skb(skb);
2316 return ERR_PTR(err);
2317 }
2318 return skb;
2319}
2320
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002321static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002322 struct msghdr *msg, size_t len,
2323 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002324{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002325 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002326 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002327 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002328 struct l2cap_hdr *lh;
2329
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002330 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002331
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002332 if (!conn)
2333 return ERR_PTR(-ENOTCONN);
2334
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002335 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002336
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002337 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002338 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002339
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002340 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002341 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002342
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002343 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002344
2345 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002346 msg->msg_flags & MSG_DONTWAIT);
2347 if (IS_ERR(skb))
2348 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002349
2350 /* Create L2CAP header */
2351 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002352 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002353 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002354
Mat Martineau18a48e72012-05-17 20:53:34 -07002355 /* Control header is populated later */
2356 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2357 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2358 else
2359 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002360
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002361 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002362 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002363
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002364 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002365 if (unlikely(err < 0)) {
2366 kfree_skb(skb);
2367 return ERR_PTR(err);
2368 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002369
Mat Martineau18a48e72012-05-17 20:53:34 -07002370 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002371 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002372 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002373}
2374
Mat Martineau94122bb2012-05-02 09:42:02 -07002375static int l2cap_segment_sdu(struct l2cap_chan *chan,
2376 struct sk_buff_head *seg_queue,
2377 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002378{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002379 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002380 u16 sdu_len;
2381 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002382 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002383
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002384 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002385
Mat Martineau94122bb2012-05-02 09:42:02 -07002386 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2387 * so fragmented skbs are not used. The HCI layer's handling
2388 * of fragmented skbs is not compatible with ERTM's queueing.
2389 */
2390
2391 /* PDU size is derived from the HCI MTU */
2392 pdu_len = chan->conn->mtu;
2393
Mat Martineaua5495742012-10-23 15:24:21 -07002394 /* Constrain PDU size for BR/EDR connections */
2395 if (!chan->hs_hcon)
2396 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002397
2398 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002399 if (chan->fcs)
2400 pdu_len -= L2CAP_FCS_SIZE;
2401
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002402 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002403
2404 /* Remote device may have requested smaller PDUs */
2405 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2406
2407 if (len <= pdu_len) {
2408 sar = L2CAP_SAR_UNSEGMENTED;
2409 sdu_len = 0;
2410 pdu_len = len;
2411 } else {
2412 sar = L2CAP_SAR_START;
2413 sdu_len = len;
2414 pdu_len -= L2CAP_SDULEN_SIZE;
2415 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002416
2417 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002418 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002419
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002420 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002421 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002422 return PTR_ERR(skb);
2423 }
2424
Mat Martineau94122bb2012-05-02 09:42:02 -07002425 bt_cb(skb)->control.sar = sar;
2426 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002427
Mat Martineau94122bb2012-05-02 09:42:02 -07002428 len -= pdu_len;
2429 if (sdu_len) {
2430 sdu_len = 0;
2431 pdu_len += L2CAP_SDULEN_SIZE;
2432 }
2433
2434 if (len <= pdu_len) {
2435 sar = L2CAP_SAR_END;
2436 pdu_len = len;
2437 } else {
2438 sar = L2CAP_SAR_CONTINUE;
2439 }
2440 }
2441
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002442 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002443}
2444
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002445int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002446 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002447{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002448 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002449 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002450 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002451
Seung-Woo Kim31e8ce82013-11-05 18:46:33 +09002452 if (!chan->conn)
2453 return -ENOTCONN;
2454
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002455 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002456 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002457 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002458 if (IS_ERR(skb))
2459 return PTR_ERR(skb);
2460
2461 l2cap_do_send(chan, skb);
2462 return len;
2463 }
2464
2465 switch (chan->mode) {
2466 case L2CAP_MODE_BASIC:
2467 /* Check outgoing MTU */
2468 if (len > chan->omtu)
2469 return -EMSGSIZE;
2470
2471 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002472 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002473 if (IS_ERR(skb))
2474 return PTR_ERR(skb);
2475
2476 l2cap_do_send(chan, skb);
2477 err = len;
2478 break;
2479
2480 case L2CAP_MODE_ERTM:
2481 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002482 /* Check outgoing MTU */
2483 if (len > chan->omtu) {
2484 err = -EMSGSIZE;
2485 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002486 }
2487
Mat Martineau94122bb2012-05-02 09:42:02 -07002488 __skb_queue_head_init(&seg_queue);
2489
2490 /* Do segmentation before calling in to the state machine,
2491 * since it's possible to block while waiting for memory
2492 * allocation.
2493 */
2494 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2495
2496 /* The channel could have been closed while segmenting,
2497 * check that it is still connected.
2498 */
2499 if (chan->state != BT_CONNECTED) {
2500 __skb_queue_purge(&seg_queue);
2501 err = -ENOTCONN;
2502 }
2503
2504 if (err)
2505 break;
2506
Mat Martineau37339372012-05-17 20:53:33 -07002507 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002508 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002509 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002510 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002511
Gustavo Padovand6603662012-05-21 13:58:22 -03002512 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002513
Mat Martineau94122bb2012-05-02 09:42:02 -07002514 /* If the skbs were not queued for sending, they'll still be in
2515 * seg_queue and need to be purged.
2516 */
2517 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002518 break;
2519
2520 default:
2521 BT_DBG("bad state %1.1x", chan->mode);
2522 err = -EBADFD;
2523 }
2524
2525 return err;
2526}
2527
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002528static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2529{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002530 struct l2cap_ctrl control;
2531 u16 seq;
2532
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002533 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002534
2535 memset(&control, 0, sizeof(control));
2536 control.sframe = 1;
2537 control.super = L2CAP_SUPER_SREJ;
2538
2539 for (seq = chan->expected_tx_seq; seq != txseq;
2540 seq = __next_seq(chan, seq)) {
2541 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2542 control.reqseq = seq;
2543 l2cap_send_sframe(chan, &control);
2544 l2cap_seq_list_append(&chan->srej_list, seq);
2545 }
2546 }
2547
2548 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002549}
2550
2551static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2552{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002553 struct l2cap_ctrl control;
2554
2555 BT_DBG("chan %p", chan);
2556
2557 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2558 return;
2559
2560 memset(&control, 0, sizeof(control));
2561 control.sframe = 1;
2562 control.super = L2CAP_SUPER_SREJ;
2563 control.reqseq = chan->srej_list.tail;
2564 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002565}
2566
2567static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2568{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002569 struct l2cap_ctrl control;
2570 u16 initial_head;
2571 u16 seq;
2572
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002573 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002574
2575 memset(&control, 0, sizeof(control));
2576 control.sframe = 1;
2577 control.super = L2CAP_SUPER_SREJ;
2578
2579 /* Capture initial list head to allow only one pass through the list. */
2580 initial_head = chan->srej_list.head;
2581
2582 do {
2583 seq = l2cap_seq_list_pop(&chan->srej_list);
2584 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2585 break;
2586
2587 control.reqseq = seq;
2588 l2cap_send_sframe(chan, &control);
2589 l2cap_seq_list_append(&chan->srej_list, seq);
2590 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002591}
2592
Mat Martineau608bcc62012-05-17 20:53:32 -07002593static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2594{
2595 struct sk_buff *acked_skb;
2596 u16 ackseq;
2597
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002598 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002599
2600 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2601 return;
2602
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002603 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002604 chan->expected_ack_seq, chan->unacked_frames);
2605
2606 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2607 ackseq = __next_seq(chan, ackseq)) {
2608
2609 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2610 if (acked_skb) {
2611 skb_unlink(acked_skb, &chan->tx_q);
2612 kfree_skb(acked_skb);
2613 chan->unacked_frames--;
2614 }
2615 }
2616
2617 chan->expected_ack_seq = reqseq;
2618
2619 if (chan->unacked_frames == 0)
2620 __clear_retrans_timer(chan);
2621
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002622 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002623}
2624
2625static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2626{
2627 BT_DBG("chan %p", chan);
2628
2629 chan->expected_tx_seq = chan->buffer_seq;
2630 l2cap_seq_list_clear(&chan->srej_list);
2631 skb_queue_purge(&chan->srej_q);
2632 chan->rx_state = L2CAP_RX_STATE_RECV;
2633}
2634
Gustavo Padovand6603662012-05-21 13:58:22 -03002635static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2636 struct l2cap_ctrl *control,
2637 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002638{
Mat Martineau608bcc62012-05-17 20:53:32 -07002639 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2640 event);
2641
2642 switch (event) {
2643 case L2CAP_EV_DATA_REQUEST:
2644 if (chan->tx_send_head == NULL)
2645 chan->tx_send_head = skb_peek(skbs);
2646
2647 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2648 l2cap_ertm_send(chan);
2649 break;
2650 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2651 BT_DBG("Enter LOCAL_BUSY");
2652 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2653
2654 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2655 /* The SREJ_SENT state must be aborted if we are to
2656 * enter the LOCAL_BUSY state.
2657 */
2658 l2cap_abort_rx_srej_sent(chan);
2659 }
2660
2661 l2cap_send_ack(chan);
2662
2663 break;
2664 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2665 BT_DBG("Exit LOCAL_BUSY");
2666 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2667
2668 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2669 struct l2cap_ctrl local_control;
2670
2671 memset(&local_control, 0, sizeof(local_control));
2672 local_control.sframe = 1;
2673 local_control.super = L2CAP_SUPER_RR;
2674 local_control.poll = 1;
2675 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002676 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002677
2678 chan->retry_count = 1;
2679 __set_monitor_timer(chan);
2680 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2681 }
2682 break;
2683 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2684 l2cap_process_reqseq(chan, control->reqseq);
2685 break;
2686 case L2CAP_EV_EXPLICIT_POLL:
2687 l2cap_send_rr_or_rnr(chan, 1);
2688 chan->retry_count = 1;
2689 __set_monitor_timer(chan);
2690 __clear_ack_timer(chan);
2691 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2692 break;
2693 case L2CAP_EV_RETRANS_TO:
2694 l2cap_send_rr_or_rnr(chan, 1);
2695 chan->retry_count = 1;
2696 __set_monitor_timer(chan);
2697 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2698 break;
2699 case L2CAP_EV_RECV_FBIT:
2700 /* Nothing to process */
2701 break;
2702 default:
2703 break;
2704 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002705}
2706
Gustavo Padovand6603662012-05-21 13:58:22 -03002707static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2708 struct l2cap_ctrl *control,
2709 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002710{
Mat Martineau608bcc62012-05-17 20:53:32 -07002711 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2712 event);
2713
2714 switch (event) {
2715 case L2CAP_EV_DATA_REQUEST:
2716 if (chan->tx_send_head == NULL)
2717 chan->tx_send_head = skb_peek(skbs);
2718 /* Queue data, but don't send. */
2719 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2720 break;
2721 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2722 BT_DBG("Enter LOCAL_BUSY");
2723 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2724
2725 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2726 /* The SREJ_SENT state must be aborted if we are to
2727 * enter the LOCAL_BUSY state.
2728 */
2729 l2cap_abort_rx_srej_sent(chan);
2730 }
2731
2732 l2cap_send_ack(chan);
2733
2734 break;
2735 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2736 BT_DBG("Exit LOCAL_BUSY");
2737 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2738
2739 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2740 struct l2cap_ctrl local_control;
2741 memset(&local_control, 0, sizeof(local_control));
2742 local_control.sframe = 1;
2743 local_control.super = L2CAP_SUPER_RR;
2744 local_control.poll = 1;
2745 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002746 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002747
2748 chan->retry_count = 1;
2749 __set_monitor_timer(chan);
2750 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2751 }
2752 break;
2753 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2754 l2cap_process_reqseq(chan, control->reqseq);
2755
2756 /* Fall through */
2757
2758 case L2CAP_EV_RECV_FBIT:
2759 if (control && control->final) {
2760 __clear_monitor_timer(chan);
2761 if (chan->unacked_frames > 0)
2762 __set_retrans_timer(chan);
2763 chan->retry_count = 0;
2764 chan->tx_state = L2CAP_TX_STATE_XMIT;
2765 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2766 }
2767 break;
2768 case L2CAP_EV_EXPLICIT_POLL:
2769 /* Ignore */
2770 break;
2771 case L2CAP_EV_MONITOR_TO:
2772 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2773 l2cap_send_rr_or_rnr(chan, 1);
2774 __set_monitor_timer(chan);
2775 chan->retry_count++;
2776 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002777 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002778 }
2779 break;
2780 default:
2781 break;
2782 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002783}
2784
Gustavo Padovand6603662012-05-21 13:58:22 -03002785static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2786 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002787{
Mat Martineau608bcc62012-05-17 20:53:32 -07002788 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2789 chan, control, skbs, event, chan->tx_state);
2790
2791 switch (chan->tx_state) {
2792 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002793 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002794 break;
2795 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002796 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002797 break;
2798 default:
2799 /* Ignore event */
2800 break;
2801 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002802}
2803
Mat Martineau4b51dae92012-05-17 20:53:37 -07002804static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2805 struct l2cap_ctrl *control)
2806{
2807 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002808 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002809}
2810
Mat Martineauf80842a2012-05-17 20:53:46 -07002811static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2812 struct l2cap_ctrl *control)
2813{
2814 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002815 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002816}
2817
Linus Torvalds1da177e2005-04-16 15:20:36 -07002818/* Copy frame to all raw sockets on that connection */
2819static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2820{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002821 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002822 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002823
2824 BT_DBG("conn %p", conn);
2825
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002826 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002827
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002828 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002829 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002830 continue;
2831
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02002832 /* Don't send frame to the channel it came from */
2833 if (bt_cb(skb)->chan == chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002834 continue;
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02002835
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002836 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002837 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002838 continue;
Gustavo Padovan80b98022012-05-27 22:27:51 -03002839 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002840 kfree_skb(nskb);
2841 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002842
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002843 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002844}
2845
2846/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002847static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2848 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002849{
2850 struct sk_buff *skb, **frag;
2851 struct l2cap_cmd_hdr *cmd;
2852 struct l2cap_hdr *lh;
2853 int len, count;
2854
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002855 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2856 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002857
Anderson Lizardo300b9622013-06-02 16:30:40 -04002858 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2859 return NULL;
2860
Linus Torvalds1da177e2005-04-16 15:20:36 -07002861 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2862 count = min_t(unsigned int, conn->mtu, len);
2863
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002864 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002865 if (!skb)
2866 return NULL;
2867
2868 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002869 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002870
2871 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002872 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002873 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002874 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002875
2876 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2877 cmd->code = code;
2878 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002879 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002880
2881 if (dlen) {
2882 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2883 memcpy(skb_put(skb, count), data, count);
2884 data += count;
2885 }
2886
2887 len -= skb->len;
2888
2889 /* Continuation fragments (no L2CAP header) */
2890 frag = &skb_shinfo(skb)->frag_list;
2891 while (len) {
2892 count = min_t(unsigned int, conn->mtu, len);
2893
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002894 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002895 if (!*frag)
2896 goto fail;
2897
2898 memcpy(skb_put(*frag, count), data, count);
2899
2900 len -= count;
2901 data += count;
2902
2903 frag = &(*frag)->next;
2904 }
2905
2906 return skb;
2907
2908fail:
2909 kfree_skb(skb);
2910 return NULL;
2911}
2912
Gustavo Padovan2d792812012-10-06 10:07:01 +01002913static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2914 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002915{
2916 struct l2cap_conf_opt *opt = *ptr;
2917 int len;
2918
2919 len = L2CAP_CONF_OPT_SIZE + opt->len;
2920 *ptr += len;
2921
2922 *type = opt->type;
2923 *olen = opt->len;
2924
2925 switch (opt->len) {
2926 case 1:
2927 *val = *((u8 *) opt->val);
2928 break;
2929
2930 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002931 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002932 break;
2933
2934 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002935 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002936 break;
2937
2938 default:
2939 *val = (unsigned long) opt->val;
2940 break;
2941 }
2942
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002943 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002944 return len;
2945}
2946
Linus Torvalds1da177e2005-04-16 15:20:36 -07002947static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2948{
2949 struct l2cap_conf_opt *opt = *ptr;
2950
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002951 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002952
2953 opt->type = type;
2954 opt->len = len;
2955
2956 switch (len) {
2957 case 1:
2958 *((u8 *) opt->val) = val;
2959 break;
2960
2961 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002962 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002963 break;
2964
2965 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002966 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002967 break;
2968
2969 default:
2970 memcpy(opt->val, (void *) val, len);
2971 break;
2972 }
2973
2974 *ptr += L2CAP_CONF_OPT_SIZE + len;
2975}
2976
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002977static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2978{
2979 struct l2cap_conf_efs efs;
2980
Szymon Janc1ec918c2011-11-16 09:32:21 +01002981 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002982 case L2CAP_MODE_ERTM:
2983 efs.id = chan->local_id;
2984 efs.stype = chan->local_stype;
2985 efs.msdu = cpu_to_le16(chan->local_msdu);
2986 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002987 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002988 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002989 break;
2990
2991 case L2CAP_MODE_STREAMING:
2992 efs.id = 1;
2993 efs.stype = L2CAP_SERV_BESTEFFORT;
2994 efs.msdu = cpu_to_le16(chan->local_msdu);
2995 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2996 efs.acc_lat = 0;
2997 efs.flush_to = 0;
2998 break;
2999
3000 default:
3001 return;
3002 }
3003
3004 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003005 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003006}
3007
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003008static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003009{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003010 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003011 ack_timer.work);
3012 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003013
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003014 BT_DBG("chan %p", chan);
3015
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003016 l2cap_chan_lock(chan);
3017
Mat Martineau03625202012-05-17 20:53:51 -07003018 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3019 chan->last_acked_seq);
3020
3021 if (frames_to_ack)
3022 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003023
3024 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003025 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003026}
3027
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003028int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003029{
Mat Martineau3c588192012-04-11 10:48:42 -07003030 int err;
3031
Mat Martineau105bdf92012-04-27 16:50:48 -07003032 chan->next_tx_seq = 0;
3033 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003034 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003035 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003036 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003037 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003038 chan->last_acked_seq = 0;
3039 chan->sdu = NULL;
3040 chan->sdu_last_frag = NULL;
3041 chan->sdu_len = 0;
3042
Mat Martineaud34c34f2012-05-14 14:49:27 -07003043 skb_queue_head_init(&chan->tx_q);
3044
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003045 chan->local_amp_id = AMP_ID_BREDR;
3046 chan->move_id = AMP_ID_BREDR;
Mat Martineau08333282012-10-23 15:24:06 -07003047 chan->move_state = L2CAP_MOVE_STABLE;
3048 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3049
Mat Martineau105bdf92012-04-27 16:50:48 -07003050 if (chan->mode != L2CAP_MODE_ERTM)
3051 return 0;
3052
3053 chan->rx_state = L2CAP_RX_STATE_RECV;
3054 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003055
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003056 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3057 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3058 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003059
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003060 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003061
Mat Martineau3c588192012-04-11 10:48:42 -07003062 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3063 if (err < 0)
3064 return err;
3065
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003066 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3067 if (err < 0)
3068 l2cap_seq_list_free(&chan->srej_list);
3069
3070 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003071}
3072
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003073static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3074{
3075 switch (mode) {
3076 case L2CAP_MODE_STREAMING:
3077 case L2CAP_MODE_ERTM:
3078 if (l2cap_mode_supported(mode, remote_feat_mask))
3079 return mode;
3080 /* fall through */
3081 default:
3082 return L2CAP_MODE_BASIC;
3083 }
3084}
3085
Marcel Holtmann848566b2013-10-01 22:59:22 -07003086static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003087{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003088 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003089}
3090
Marcel Holtmann848566b2013-10-01 22:59:22 -07003091static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003092{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003093 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003094}
3095
Mat Martineau36c86c82012-10-23 15:24:20 -07003096static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3097 struct l2cap_conf_rfc *rfc)
3098{
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003099 if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) {
Mat Martineau36c86c82012-10-23 15:24:20 -07003100 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3101
3102 /* Class 1 devices have must have ERTM timeouts
3103 * exceeding the Link Supervision Timeout. The
3104 * default Link Supervision Timeout for AMP
3105 * controllers is 10 seconds.
3106 *
3107 * Class 1 devices use 0xffffffff for their
3108 * best-effort flush timeout, so the clamping logic
3109 * will result in a timeout that meets the above
3110 * requirement. ERTM timeouts are 16-bit values, so
3111 * the maximum timeout is 65.535 seconds.
3112 */
3113
3114 /* Convert timeout to milliseconds and round */
3115 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3116
3117 /* This is the recommended formula for class 2 devices
3118 * that start ERTM timers when packets are sent to the
3119 * controller.
3120 */
3121 ertm_to = 3 * ertm_to + 500;
3122
3123 if (ertm_to > 0xffff)
3124 ertm_to = 0xffff;
3125
3126 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3127 rfc->monitor_timeout = rfc->retrans_timeout;
3128 } else {
3129 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3130 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3131 }
3132}
3133
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003134static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3135{
3136 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Marcel Holtmann848566b2013-10-01 22:59:22 -07003137 __l2cap_ews_supported(chan->conn)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003138 /* use extended control field */
3139 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003140 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3141 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003142 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003143 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003144 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3145 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003146 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003147}
3148
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003149static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003150{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003151 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003152 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003153 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003154 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003155
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003156 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003157
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003158 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003159 goto done;
3160
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003161 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003162 case L2CAP_MODE_STREAMING:
3163 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003164 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003165 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003166
Marcel Holtmann848566b2013-10-01 22:59:22 -07003167 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003168 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3169
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003170 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003171 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003172 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003173 break;
3174 }
3175
3176done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003177 if (chan->imtu != L2CAP_DEFAULT_MTU)
3178 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003179
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003180 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003181 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003182 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003183 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003184 break;
3185
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003186 rfc.mode = L2CAP_MODE_BASIC;
3187 rfc.txwin_size = 0;
3188 rfc.max_transmit = 0;
3189 rfc.retrans_timeout = 0;
3190 rfc.monitor_timeout = 0;
3191 rfc.max_pdu_size = 0;
3192
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003193 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003194 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003195 break;
3196
3197 case L2CAP_MODE_ERTM:
3198 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003199 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003200
3201 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003202
3203 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003204 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3205 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003206 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003207
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003208 l2cap_txwin_setup(chan);
3209
3210 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003211 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003212
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003213 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003214 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003215
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003216 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3217 l2cap_add_opt_efs(&ptr, chan);
3218
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003219 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3220 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003221 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003222
3223 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3224 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003225 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003226 chan->fcs = L2CAP_FCS_NONE;
3227 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3228 chan->fcs);
3229 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003230 break;
3231
3232 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003233 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003234 rfc.mode = L2CAP_MODE_STREAMING;
3235 rfc.txwin_size = 0;
3236 rfc.max_transmit = 0;
3237 rfc.retrans_timeout = 0;
3238 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003239
3240 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003241 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3242 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003243 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003244
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003245 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003246 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003247
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003248 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3249 l2cap_add_opt_efs(&ptr, chan);
3250
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003251 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3252 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003253 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003254 chan->fcs = L2CAP_FCS_NONE;
3255 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3256 chan->fcs);
3257 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003258 break;
3259 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003260
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003261 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003262 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003263
3264 return ptr - data;
3265}
3266
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003267static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003268{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003269 struct l2cap_conf_rsp *rsp = data;
3270 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003271 void *req = chan->conf_req;
3272 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003273 int type, hint, olen;
3274 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003275 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003276 struct l2cap_conf_efs efs;
3277 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003278 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003279 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003280 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003281
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003282 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003283
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003284 while (len >= L2CAP_CONF_OPT_SIZE) {
3285 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003286
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003287 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003288 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003289
3290 switch (type) {
3291 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003292 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003293 break;
3294
3295 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003296 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003297 break;
3298
3299 case L2CAP_CONF_QOS:
3300 break;
3301
Marcel Holtmann6464f352007-10-20 13:39:51 +02003302 case L2CAP_CONF_RFC:
3303 if (olen == sizeof(rfc))
3304 memcpy(&rfc, (void *) val, olen);
3305 break;
3306
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003307 case L2CAP_CONF_FCS:
3308 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003309 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003310 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003311
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003312 case L2CAP_CONF_EFS:
3313 remote_efs = 1;
3314 if (olen == sizeof(efs))
3315 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003316 break;
3317
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003318 case L2CAP_CONF_EWS:
Marcel Holtmann848566b2013-10-01 22:59:22 -07003319 if (!chan->conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003320 return -ECONNREFUSED;
3321
3322 set_bit(FLAG_EXT_CTRL, &chan->flags);
3323 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003324 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003325 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003326 break;
3327
3328 default:
3329 if (hint)
3330 break;
3331
3332 result = L2CAP_CONF_UNKNOWN;
3333 *((u8 *) ptr++) = type;
3334 break;
3335 }
3336 }
3337
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003338 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003339 goto done;
3340
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003341 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003342 case L2CAP_MODE_STREAMING:
3343 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003344 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003345 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003346 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003347 break;
3348 }
3349
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003350 if (remote_efs) {
Marcel Holtmann848566b2013-10-01 22:59:22 -07003351 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003352 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3353 else
3354 return -ECONNREFUSED;
3355 }
3356
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003357 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003358 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003359
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003360 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003361 }
3362
3363done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003364 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003365 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003366 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003367
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003368 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003369 return -ECONNREFUSED;
3370
Gustavo Padovan2d792812012-10-06 10:07:01 +01003371 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3372 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003373 }
3374
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003375 if (result == L2CAP_CONF_SUCCESS) {
3376 /* Configure output options and let the other side know
3377 * which ones we don't like. */
3378
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003379 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3380 result = L2CAP_CONF_UNACCEPT;
3381 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003382 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003383 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003384 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003385 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003386
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003387 if (remote_efs) {
3388 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003389 efs.stype != L2CAP_SERV_NOTRAFIC &&
3390 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003391
3392 result = L2CAP_CONF_UNACCEPT;
3393
3394 if (chan->num_conf_req >= 1)
3395 return -ECONNREFUSED;
3396
3397 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003398 sizeof(efs),
3399 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003400 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003401 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003402 result = L2CAP_CONF_PENDING;
3403 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003404 }
3405 }
3406
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003407 switch (rfc.mode) {
3408 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003409 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003410 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003411 break;
3412
3413 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003414 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3415 chan->remote_tx_win = rfc.txwin_size;
3416 else
3417 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3418
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003419 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003420
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003421 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003422 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3423 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003424 rfc.max_pdu_size = cpu_to_le16(size);
3425 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003426
Mat Martineau36c86c82012-10-23 15:24:20 -07003427 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003428
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003429 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003430
3431 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003432 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003433
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003434 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3435 chan->remote_id = efs.id;
3436 chan->remote_stype = efs.stype;
3437 chan->remote_msdu = le16_to_cpu(efs.msdu);
3438 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003439 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003440 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003441 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003442 chan->remote_sdu_itime =
3443 le32_to_cpu(efs.sdu_itime);
3444 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003445 sizeof(efs),
3446 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003447 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003448 break;
3449
3450 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003451 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003452 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3453 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003454 rfc.max_pdu_size = cpu_to_le16(size);
3455 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003456
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003457 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003458
Gustavo Padovan2d792812012-10-06 10:07:01 +01003459 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3460 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003461
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003462 break;
3463
3464 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003465 result = L2CAP_CONF_UNACCEPT;
3466
3467 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003468 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003469 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003470
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003471 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003472 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003473 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003474 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003475 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003476 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003477
3478 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003479}
3480
Gustavo Padovan2d792812012-10-06 10:07:01 +01003481static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3482 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003483{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003484 struct l2cap_conf_req *req = data;
3485 void *ptr = req->data;
3486 int type, olen;
3487 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003488 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003489 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003490
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003491 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003492
3493 while (len >= L2CAP_CONF_OPT_SIZE) {
3494 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3495
3496 switch (type) {
3497 case L2CAP_CONF_MTU:
3498 if (val < L2CAP_DEFAULT_MIN_MTU) {
3499 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003500 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003501 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003502 chan->imtu = val;
3503 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003504 break;
3505
3506 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003507 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003508 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003509 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003510 break;
3511
3512 case L2CAP_CONF_RFC:
3513 if (olen == sizeof(rfc))
3514 memcpy(&rfc, (void *)val, olen);
3515
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003516 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003517 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003518 return -ECONNREFUSED;
3519
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003520 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003521
3522 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003523 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003524 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003525
3526 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003527 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003528 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003529 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003530 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003531
3532 case L2CAP_CONF_EFS:
3533 if (olen == sizeof(efs))
3534 memcpy(&efs, (void *)val, olen);
3535
3536 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003537 efs.stype != L2CAP_SERV_NOTRAFIC &&
3538 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003539 return -ECONNREFUSED;
3540
Gustavo Padovan2d792812012-10-06 10:07:01 +01003541 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3542 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003543 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003544
3545 case L2CAP_CONF_FCS:
3546 if (*result == L2CAP_CONF_PENDING)
3547 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003548 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003549 &chan->conf_state);
3550 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003551 }
3552 }
3553
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003554 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003555 return -ECONNREFUSED;
3556
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003557 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003558
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003559 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003560 switch (rfc.mode) {
3561 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003562 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3563 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3564 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003565 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3566 chan->ack_win = min_t(u16, chan->ack_win,
3567 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003568
3569 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3570 chan->local_msdu = le16_to_cpu(efs.msdu);
3571 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003572 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003573 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3574 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003575 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003576 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003577 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003578
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003579 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003580 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003581 }
3582 }
3583
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003584 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003585 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003586
3587 return ptr - data;
3588}
3589
Gustavo Padovan2d792812012-10-06 10:07:01 +01003590static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3591 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003592{
3593 struct l2cap_conf_rsp *rsp = data;
3594 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003595
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003596 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003597
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003598 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003599 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003600 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003601
3602 return ptr - data;
3603}
3604
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003605void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003606{
3607 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003608 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003609 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003610 u8 rsp_code;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003611
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003612 rsp.scid = cpu_to_le16(chan->dcid);
3613 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003614 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3615 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003616
3617 if (chan->hs_hcon)
3618 rsp_code = L2CAP_CREATE_CHAN_RSP;
3619 else
3620 rsp_code = L2CAP_CONN_RSP;
3621
3622 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3623
3624 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003625
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003626 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003627 return;
3628
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003629 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003630 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003631 chan->num_conf_req++;
3632}
3633
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003634static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003635{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003636 int type, olen;
3637 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003638 /* Use sane default values in case a misbehaving remote device
3639 * did not send an RFC or extended window size option.
3640 */
3641 u16 txwin_ext = chan->ack_win;
3642 struct l2cap_conf_rfc rfc = {
3643 .mode = chan->mode,
3644 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3645 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3646 .max_pdu_size = cpu_to_le16(chan->imtu),
3647 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3648 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003649
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003650 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003651
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003652 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003653 return;
3654
3655 while (len >= L2CAP_CONF_OPT_SIZE) {
3656 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3657
Mat Martineauc20f8e32012-07-10 05:47:07 -07003658 switch (type) {
3659 case L2CAP_CONF_RFC:
3660 if (olen == sizeof(rfc))
3661 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003662 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003663 case L2CAP_CONF_EWS:
3664 txwin_ext = val;
3665 break;
3666 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003667 }
3668
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003669 switch (rfc.mode) {
3670 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003671 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3672 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003673 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3674 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3675 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3676 else
3677 chan->ack_win = min_t(u16, chan->ack_win,
3678 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003679 break;
3680 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003681 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003682 }
3683}
3684
Gustavo Padovan2d792812012-10-06 10:07:01 +01003685static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003686 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3687 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003688{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003689 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003690
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003691 if (cmd_len < sizeof(*rej))
3692 return -EPROTO;
3693
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003694 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003695 return 0;
3696
3697 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003698 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003699 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003700
3701 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003702 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003703
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003704 l2cap_conn_start(conn);
3705 }
3706
3707 return 0;
3708}
3709
Mat Martineau17009152012-10-23 15:24:07 -07003710static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3711 struct l2cap_cmd_hdr *cmd,
3712 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003713{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003714 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3715 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003716 struct l2cap_chan *chan = NULL, *pchan;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003717 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003718
3719 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003720 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003721
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003722 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003723
3724 /* Check if we have socket listening on psm */
Marcel Holtmann6f59b902013-10-13 05:24:01 -07003725 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03003726 &conn->hcon->dst, ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003727 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003728 result = L2CAP_CR_BAD_PSM;
3729 goto sendresp;
3730 }
3731
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003732 mutex_lock(&conn->chan_lock);
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02003733 l2cap_chan_lock(pchan);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003734
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003735 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003736 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003737 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003738 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003739 result = L2CAP_CR_SEC_BLOCK;
3740 goto response;
3741 }
3742
Linus Torvalds1da177e2005-04-16 15:20:36 -07003743 result = L2CAP_CR_NO_MEM;
3744
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003745 /* Check if we already have channel with that dcid */
3746 if (__l2cap_get_chan_by_dcid(conn, scid))
3747 goto response;
3748
Gustavo Padovan80b98022012-05-27 22:27:51 -03003749 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003750 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003751 goto response;
3752
Syam Sidhardhan330b6c12013-08-06 01:59:12 +09003753 /* For certain devices (ex: HID mouse), support for authentication,
3754 * pairing and bonding is optional. For such devices, inorder to avoid
3755 * the ACL alive for too long after L2CAP disconnection, reset the ACL
3756 * disc_timeout back to HCI_DISCONN_TIMEOUT during L2CAP connect.
3757 */
3758 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
3759
Marcel Holtmann7eafc592013-10-13 08:12:47 -07003760 bacpy(&chan->src, &conn->hcon->src);
3761 bacpy(&chan->dst, &conn->hcon->dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07003762 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
3763 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003764 chan->psm = psm;
3765 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003766 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003767
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003768 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003769
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003770 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003771
Gustavo Padovan8d836d72013-10-15 19:24:47 -03003772 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003773
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003774 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003775
Marcel Holtmann984947d2009-02-06 23:35:19 +01003776 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003777 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07003778 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003779 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003780 result = L2CAP_CR_PEND;
3781 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003782 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003783 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003784 /* Force pending result for AMP controllers.
3785 * The connection will succeed after the
3786 * physical link is up.
3787 */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003788 if (amp_id == AMP_ID_BREDR) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003789 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau17009152012-10-23 15:24:07 -07003790 result = L2CAP_CR_SUCCESS;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003791 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003792 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003793 result = L2CAP_CR_PEND;
Mat Martineau17009152012-10-23 15:24:07 -07003794 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003795 status = L2CAP_CS_NO_INFO;
3796 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003797 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003798 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003799 result = L2CAP_CR_PEND;
3800 status = L2CAP_CS_AUTHEN_PEND;
3801 }
3802 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02003803 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003804 result = L2CAP_CR_PEND;
3805 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003806 }
3807
Linus Torvalds1da177e2005-04-16 15:20:36 -07003808response:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02003809 l2cap_chan_unlock(pchan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003810 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003811
3812sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003813 rsp.scid = cpu_to_le16(scid);
3814 rsp.dcid = cpu_to_le16(dcid);
3815 rsp.result = cpu_to_le16(result);
3816 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003817 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003818
3819 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3820 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003821 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003822
3823 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3824 conn->info_ident = l2cap_get_ident(conn);
3825
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003826 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003827
Gustavo Padovan2d792812012-10-06 10:07:01 +01003828 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3829 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003830 }
3831
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003832 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003833 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003834 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003835 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003836 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003837 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003838 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003839 }
Mat Martineau17009152012-10-23 15:24:07 -07003840
3841 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003842}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003843
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003844static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003845 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003846{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303847 struct hci_dev *hdev = conn->hcon->hdev;
3848 struct hci_conn *hcon = conn->hcon;
3849
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003850 if (cmd_len < sizeof(struct l2cap_conn_req))
3851 return -EPROTO;
3852
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303853 hci_dev_lock(hdev);
3854 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3855 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3856 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3857 hcon->dst_type, 0, NULL, 0,
3858 hcon->dev_class);
3859 hci_dev_unlock(hdev);
3860
Gustavo Padovan300229f2012-10-12 19:40:40 +08003861 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003862 return 0;
3863}
3864
Mat Martineau5909cf32012-10-23 15:24:08 -07003865static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003866 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3867 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003868{
3869 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3870 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003871 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003872 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003873 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003874
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003875 if (cmd_len < sizeof(*rsp))
3876 return -EPROTO;
3877
Linus Torvalds1da177e2005-04-16 15:20:36 -07003878 scid = __le16_to_cpu(rsp->scid);
3879 dcid = __le16_to_cpu(rsp->dcid);
3880 result = __le16_to_cpu(rsp->result);
3881 status = __le16_to_cpu(rsp->status);
3882
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003883 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 +01003884 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003885
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003886 mutex_lock(&conn->chan_lock);
3887
Linus Torvalds1da177e2005-04-16 15:20:36 -07003888 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003889 chan = __l2cap_get_chan_by_scid(conn, scid);
3890 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003891 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003892 goto unlock;
3893 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003894 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003895 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3896 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003897 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003898 goto unlock;
3899 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003900 }
3901
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003902 err = 0;
3903
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003904 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003905
Linus Torvalds1da177e2005-04-16 15:20:36 -07003906 switch (result) {
3907 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03003908 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003909 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003910 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003911 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003912
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003913 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003914 break;
3915
Linus Torvalds1da177e2005-04-16 15:20:36 -07003916 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003917 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003918 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003919 break;
3920
3921 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003922 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003923 break;
3924
3925 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003926 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003927 break;
3928 }
3929
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003930 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003931
3932unlock:
3933 mutex_unlock(&conn->chan_lock);
3934
3935 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003936}
3937
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003938static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003939{
3940 /* FCS is enabled only in ERTM or streaming mode, if one or both
3941 * sides request it.
3942 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003943 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003944 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003945 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003946 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003947}
3948
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003949static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3950 u8 ident, u16 flags)
3951{
3952 struct l2cap_conn *conn = chan->conn;
3953
3954 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3955 flags);
3956
3957 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3958 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3959
3960 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
3961 l2cap_build_conf_rsp(chan, data,
3962 L2CAP_CONF_SUCCESS, flags), data);
3963}
3964
Johan Hedberg662d6522013-10-16 11:20:47 +03003965static void cmd_reject_invalid_cid(struct l2cap_conn *conn, u8 ident,
3966 u16 scid, u16 dcid)
3967{
3968 struct l2cap_cmd_rej_cid rej;
3969
3970 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
3971 rej.scid = __cpu_to_le16(scid);
3972 rej.dcid = __cpu_to_le16(dcid);
3973
3974 l2cap_send_cmd(conn, ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3975}
3976
Gustavo Padovan2d792812012-10-06 10:07:01 +01003977static inline int l2cap_config_req(struct l2cap_conn *conn,
3978 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3979 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003980{
3981 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3982 u16 dcid, flags;
3983 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003984 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003985 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003986
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003987 if (cmd_len < sizeof(*req))
3988 return -EPROTO;
3989
Linus Torvalds1da177e2005-04-16 15:20:36 -07003990 dcid = __le16_to_cpu(req->dcid);
3991 flags = __le16_to_cpu(req->flags);
3992
3993 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3994
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003995 chan = l2cap_get_chan_by_scid(conn, dcid);
Johan Hedberg662d6522013-10-16 11:20:47 +03003996 if (!chan) {
3997 cmd_reject_invalid_cid(conn, cmd->ident, dcid, 0);
3998 return 0;
3999 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004000
David S. Miller033b1142011-07-21 13:38:42 -07004001 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Johan Hedberg662d6522013-10-16 11:20:47 +03004002 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4003 chan->dcid);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004004 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004005 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004006
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004007 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07004008 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004009 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004010 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004011 l2cap_build_conf_rsp(chan, rsp,
4012 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004013 goto unlock;
4014 }
4015
4016 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004017 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4018 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004019
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004020 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004021 /* Incomplete config. Send empty response. */
4022 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004023 l2cap_build_conf_rsp(chan, rsp,
4024 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004025 goto unlock;
4026 }
4027
4028 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004029 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004030 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004031 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004032 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004033 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004034
Mat Martineau1500109b2012-10-23 15:24:15 -07004035 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004036 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004037 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004038
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004039 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004040 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004041
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004042 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004043 goto unlock;
4044
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004045 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004046 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004047
Mat Martineau105bdf92012-04-27 16:50:48 -07004048 if (chan->mode == L2CAP_MODE_ERTM ||
4049 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004050 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004051
Mat Martineau3c588192012-04-11 10:48:42 -07004052 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004053 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004054 else
4055 l2cap_chan_ready(chan);
4056
Marcel Holtmann876d9482007-10-20 13:35:42 +02004057 goto unlock;
4058 }
4059
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004060 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004061 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004062 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004063 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004064 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004065 }
4066
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004067 /* Got Conf Rsp PENDING from remote side and asume we sent
4068 Conf Rsp PENDING in the code above */
4069 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004070 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004071
4072 /* check compatibility */
4073
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004074 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004075 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004076 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4077 else
4078 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004079 }
4080
Linus Torvalds1da177e2005-04-16 15:20:36 -07004081unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004082 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004083 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004084}
4085
Gustavo Padovan2d792812012-10-06 10:07:01 +01004086static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004087 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4088 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004089{
4090 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4091 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004092 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004093 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004094 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004095
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004096 if (cmd_len < sizeof(*rsp))
4097 return -EPROTO;
4098
Linus Torvalds1da177e2005-04-16 15:20:36 -07004099 scid = __le16_to_cpu(rsp->scid);
4100 flags = __le16_to_cpu(rsp->flags);
4101 result = __le16_to_cpu(rsp->result);
4102
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004103 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4104 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004105
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004106 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004107 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004108 return 0;
4109
4110 switch (result) {
4111 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004112 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004113 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004114 break;
4115
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004116 case L2CAP_CONF_PENDING:
4117 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4118
4119 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4120 char buf[64];
4121
4122 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004123 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004124 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004125 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004126 goto done;
4127 }
4128
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004129 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004130 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4131 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004132 } else {
4133 if (l2cap_check_efs(chan)) {
4134 amp_create_logical_link(chan);
4135 chan->ident = cmd->ident;
4136 }
4137 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004138 }
4139 goto done;
4140
Linus Torvalds1da177e2005-04-16 15:20:36 -07004141 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004142 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004143 char req[64];
4144
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004145 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004146 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004147 goto done;
4148 }
4149
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004150 /* throw out any old stored conf requests */
4151 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004152 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004153 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004154 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004155 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004156 goto done;
4157 }
4158
4159 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004160 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004161 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004162 if (result != L2CAP_CONF_SUCCESS)
4163 goto done;
4164 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004165 }
4166
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004167 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004168 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004169
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004170 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004171 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004172 goto done;
4173 }
4174
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004175 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004176 goto done;
4177
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004178 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004179
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004180 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004181 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004182
Mat Martineau105bdf92012-04-27 16:50:48 -07004183 if (chan->mode == L2CAP_MODE_ERTM ||
4184 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004185 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004186
Mat Martineau3c588192012-04-11 10:48:42 -07004187 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004188 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004189 else
4190 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004191 }
4192
4193done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004194 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004195 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004196}
4197
Gustavo Padovan2d792812012-10-06 10:07:01 +01004198static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004199 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4200 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004201{
4202 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4203 struct l2cap_disconn_rsp rsp;
4204 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004205 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004206
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004207 if (cmd_len != sizeof(*req))
4208 return -EPROTO;
4209
Linus Torvalds1da177e2005-04-16 15:20:36 -07004210 scid = __le16_to_cpu(req->scid);
4211 dcid = __le16_to_cpu(req->dcid);
4212
4213 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4214
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004215 mutex_lock(&conn->chan_lock);
4216
4217 chan = __l2cap_get_chan_by_scid(conn, dcid);
4218 if (!chan) {
4219 mutex_unlock(&conn->chan_lock);
Johan Hedberg662d6522013-10-16 11:20:47 +03004220 cmd_reject_invalid_cid(conn, cmd->ident, dcid, scid);
4221 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004222 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004223
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004224 l2cap_chan_lock(chan);
4225
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004226 rsp.dcid = cpu_to_le16(chan->scid);
4227 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004228 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4229
Gustavo Padovan5ec1bbe2013-10-15 19:24:48 -03004230 chan->ops->set_shutdown(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004231
Mat Martineau61d6ef32012-04-27 16:50:50 -07004232 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004233 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004234
4235 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004236
Gustavo Padovan80b98022012-05-27 22:27:51 -03004237 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004238 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004239
4240 mutex_unlock(&conn->chan_lock);
4241
Linus Torvalds1da177e2005-04-16 15:20:36 -07004242 return 0;
4243}
4244
Gustavo Padovan2d792812012-10-06 10:07:01 +01004245static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004246 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4247 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004248{
4249 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4250 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004251 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004252
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004253 if (cmd_len != sizeof(*rsp))
4254 return -EPROTO;
4255
Linus Torvalds1da177e2005-04-16 15:20:36 -07004256 scid = __le16_to_cpu(rsp->scid);
4257 dcid = __le16_to_cpu(rsp->dcid);
4258
4259 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4260
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004261 mutex_lock(&conn->chan_lock);
4262
4263 chan = __l2cap_get_chan_by_scid(conn, scid);
4264 if (!chan) {
4265 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004266 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004267 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004268
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004269 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004270
Mat Martineau61d6ef32012-04-27 16:50:50 -07004271 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004272 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004273
4274 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004275
Gustavo Padovan80b98022012-05-27 22:27:51 -03004276 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004277 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004278
4279 mutex_unlock(&conn->chan_lock);
4280
Linus Torvalds1da177e2005-04-16 15:20:36 -07004281 return 0;
4282}
4283
Gustavo Padovan2d792812012-10-06 10:07:01 +01004284static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004285 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4286 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004287{
4288 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004289 u16 type;
4290
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004291 if (cmd_len != sizeof(*req))
4292 return -EPROTO;
4293
Linus Torvalds1da177e2005-04-16 15:20:36 -07004294 type = __le16_to_cpu(req->type);
4295
4296 BT_DBG("type 0x%4.4x", type);
4297
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004298 if (type == L2CAP_IT_FEAT_MASK) {
4299 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004300 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004301 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004302 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4303 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004304 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004305 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004306 | L2CAP_FEAT_FCS;
Marcel Holtmann848566b2013-10-01 22:59:22 -07004307 if (conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004308 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004309 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004310
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004311 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004312 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4313 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004314 } else if (type == L2CAP_IT_FIXED_CHAN) {
4315 u8 buf[12];
4316 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004317
Marcel Holtmann848566b2013-10-01 22:59:22 -07004318 if (conn->hs_enabled)
Mat Martineau50a147c2011-11-02 16:18:34 -07004319 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4320 else
4321 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4322
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004323 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4324 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004325 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004326 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4327 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004328 } else {
4329 struct l2cap_info_rsp rsp;
4330 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004331 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004332 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4333 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004334 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004335
4336 return 0;
4337}
4338
Gustavo Padovan2d792812012-10-06 10:07:01 +01004339static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004340 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4341 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004342{
4343 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4344 u16 type, result;
4345
Jaganath Kanakkassery3f6fa3d2013-06-21 19:55:11 +05304346 if (cmd_len < sizeof(*rsp))
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004347 return -EPROTO;
4348
Linus Torvalds1da177e2005-04-16 15:20:36 -07004349 type = __le16_to_cpu(rsp->type);
4350 result = __le16_to_cpu(rsp->result);
4351
4352 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4353
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004354 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4355 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004356 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004357 return 0;
4358
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004359 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004360
Ville Tervoadb08ed2010-08-04 09:43:33 +03004361 if (result != L2CAP_IR_SUCCESS) {
4362 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4363 conn->info_ident = 0;
4364
4365 l2cap_conn_start(conn);
4366
4367 return 0;
4368 }
4369
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004370 switch (type) {
4371 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004372 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004373
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004374 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004375 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004376 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004377
4378 conn->info_ident = l2cap_get_ident(conn);
4379
4380 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004381 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004382 } else {
4383 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4384 conn->info_ident = 0;
4385
4386 l2cap_conn_start(conn);
4387 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004388 break;
4389
4390 case L2CAP_IT_FIXED_CHAN:
4391 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004392 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004393 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004394
4395 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004396 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004397 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004398
Linus Torvalds1da177e2005-04-16 15:20:36 -07004399 return 0;
4400}
4401
Mat Martineau17009152012-10-23 15:24:07 -07004402static int l2cap_create_channel_req(struct l2cap_conn *conn,
4403 struct l2cap_cmd_hdr *cmd,
4404 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004405{
4406 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004407 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004408 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004409 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004410 u16 psm, scid;
4411
4412 if (cmd_len != sizeof(*req))
4413 return -EPROTO;
4414
Marcel Holtmann848566b2013-10-01 22:59:22 -07004415 if (!conn->hs_enabled)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004416 return -EINVAL;
4417
4418 psm = le16_to_cpu(req->psm);
4419 scid = le16_to_cpu(req->scid);
4420
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004421 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 -07004422
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004423 /* For controller id 0 make BR/EDR connection */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004424 if (req->amp_id == AMP_ID_BREDR) {
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004425 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4426 req->amp_id);
4427 return 0;
4428 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004429
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004430 /* Validate AMP controller id */
4431 hdev = hci_dev_get(req->amp_id);
4432 if (!hdev)
4433 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004434
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004435 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004436 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004437 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004438 }
4439
4440 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4441 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004442 if (chan) {
4443 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4444 struct hci_conn *hs_hcon;
4445
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07004446 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
4447 &conn->hcon->dst);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004448 if (!hs_hcon) {
4449 hci_dev_put(hdev);
Johan Hedberg662d6522013-10-16 11:20:47 +03004450 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4451 chan->dcid);
4452 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004453 }
4454
4455 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4456
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004457 mgr->bredr_chan = chan;
4458 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004459 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004460 conn->mtu = hdev->block_mtu;
4461 }
4462
4463 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004464
4465 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004466
4467error:
4468 rsp.dcid = 0;
4469 rsp.scid = cpu_to_le16(scid);
4470 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4471 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4472
4473 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4474 sizeof(rsp), &rsp);
4475
Johan Hedbergdc280802013-09-16 13:05:13 +03004476 return 0;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004477}
4478
Mat Martineau8eb200b2012-10-23 15:24:17 -07004479static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4480{
4481 struct l2cap_move_chan_req req;
4482 u8 ident;
4483
4484 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4485
4486 ident = l2cap_get_ident(chan->conn);
4487 chan->ident = ident;
4488
4489 req.icid = cpu_to_le16(chan->scid);
4490 req.dest_amp_id = dest_amp_id;
4491
4492 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4493 &req);
4494
4495 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4496}
4497
Mat Martineau1500109b2012-10-23 15:24:15 -07004498static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004499{
4500 struct l2cap_move_chan_rsp rsp;
4501
Mat Martineau1500109b2012-10-23 15:24:15 -07004502 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004503
Mat Martineau1500109b2012-10-23 15:24:15 -07004504 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004505 rsp.result = cpu_to_le16(result);
4506
Mat Martineau1500109b2012-10-23 15:24:15 -07004507 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4508 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004509}
4510
Mat Martineau5b155ef2012-10-23 15:24:14 -07004511static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004512{
4513 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004514
Mat Martineau5b155ef2012-10-23 15:24:14 -07004515 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004516
Mat Martineau5b155ef2012-10-23 15:24:14 -07004517 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004518
Mat Martineau5b155ef2012-10-23 15:24:14 -07004519 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004520 cfm.result = cpu_to_le16(result);
4521
Mat Martineau5b155ef2012-10-23 15:24:14 -07004522 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4523 sizeof(cfm), &cfm);
4524
4525 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4526}
4527
4528static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4529{
4530 struct l2cap_move_chan_cfm cfm;
4531
4532 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4533
4534 cfm.icid = cpu_to_le16(icid);
4535 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4536
4537 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4538 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004539}
4540
4541static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004542 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004543{
4544 struct l2cap_move_chan_cfm_rsp rsp;
4545
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004546 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004547
4548 rsp.icid = cpu_to_le16(icid);
4549 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4550}
4551
Mat Martineau5f3847a2012-10-23 15:24:12 -07004552static void __release_logical_link(struct l2cap_chan *chan)
4553{
4554 chan->hs_hchan = NULL;
4555 chan->hs_hcon = NULL;
4556
4557 /* Placeholder - release the logical link */
4558}
4559
Mat Martineau1500109b2012-10-23 15:24:15 -07004560static void l2cap_logical_fail(struct l2cap_chan *chan)
4561{
4562 /* Logical link setup failed */
4563 if (chan->state != BT_CONNECTED) {
4564 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004565 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004566 return;
4567 }
4568
4569 switch (chan->move_role) {
4570 case L2CAP_MOVE_ROLE_RESPONDER:
4571 l2cap_move_done(chan);
4572 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4573 break;
4574 case L2CAP_MOVE_ROLE_INITIATOR:
4575 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4576 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4577 /* Remote has only sent pending or
4578 * success responses, clean up
4579 */
4580 l2cap_move_done(chan);
4581 }
4582
4583 /* Other amp move states imply that the move
4584 * has already aborted
4585 */
4586 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4587 break;
4588 }
4589}
4590
4591static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4592 struct hci_chan *hchan)
4593{
4594 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004595
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004596 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004597 chan->hs_hcon->l2cap_data = chan->conn;
4598
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004599 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004600
4601 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004602 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004603
4604 set_default_fcs(chan);
4605
4606 err = l2cap_ertm_init(chan);
4607 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004608 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004609 else
4610 l2cap_chan_ready(chan);
4611 }
4612}
4613
4614static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4615 struct hci_chan *hchan)
4616{
4617 chan->hs_hcon = hchan->conn;
4618 chan->hs_hcon->l2cap_data = chan->conn;
4619
4620 BT_DBG("move_state %d", chan->move_state);
4621
4622 switch (chan->move_state) {
4623 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4624 /* Move confirm will be sent after a success
4625 * response is received
4626 */
4627 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4628 break;
4629 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4630 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4631 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4632 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4633 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4634 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4635 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4636 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4637 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4638 }
4639 break;
4640 default:
4641 /* Move was not in expected state, free the channel */
4642 __release_logical_link(chan);
4643
4644 chan->move_state = L2CAP_MOVE_STABLE;
4645 }
4646}
4647
4648/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004649void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4650 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004651{
Mat Martineau1500109b2012-10-23 15:24:15 -07004652 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4653
4654 if (status) {
4655 l2cap_logical_fail(chan);
4656 __release_logical_link(chan);
4657 return;
4658 }
4659
4660 if (chan->state != BT_CONNECTED) {
4661 /* Ignore logical link if channel is on BR/EDR */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004662 if (chan->local_amp_id != AMP_ID_BREDR)
Mat Martineau1500109b2012-10-23 15:24:15 -07004663 l2cap_logical_finish_create(chan, hchan);
4664 } else {
4665 l2cap_logical_finish_move(chan, hchan);
4666 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004667}
4668
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004669void l2cap_move_start(struct l2cap_chan *chan)
4670{
4671 BT_DBG("chan %p", chan);
4672
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004673 if (chan->local_amp_id == AMP_ID_BREDR) {
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004674 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4675 return;
4676 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4677 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4678 /* Placeholder - start physical link setup */
4679 } else {
4680 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4681 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4682 chan->move_id = 0;
4683 l2cap_move_setup(chan);
4684 l2cap_send_move_chan_req(chan, 0);
4685 }
4686}
4687
Mat Martineau8eb200b2012-10-23 15:24:17 -07004688static void l2cap_do_create(struct l2cap_chan *chan, int result,
4689 u8 local_amp_id, u8 remote_amp_id)
4690{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004691 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4692 local_amp_id, remote_amp_id);
4693
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004694 chan->fcs = L2CAP_FCS_NONE;
4695
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004696 /* Outgoing channel on AMP */
4697 if (chan->state == BT_CONNECT) {
4698 if (result == L2CAP_CR_SUCCESS) {
4699 chan->local_amp_id = local_amp_id;
4700 l2cap_send_create_chan_req(chan, remote_amp_id);
4701 } else {
4702 /* Revert to BR/EDR connect */
4703 l2cap_send_conn_req(chan);
4704 }
4705
4706 return;
4707 }
4708
4709 /* Incoming channel on AMP */
4710 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004711 struct l2cap_conn_rsp rsp;
4712 char buf[128];
4713 rsp.scid = cpu_to_le16(chan->dcid);
4714 rsp.dcid = cpu_to_le16(chan->scid);
4715
Mat Martineau8eb200b2012-10-23 15:24:17 -07004716 if (result == L2CAP_CR_SUCCESS) {
4717 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004718 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4719 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004720 } else {
4721 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004722 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4723 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004724 }
4725
4726 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4727 sizeof(rsp), &rsp);
4728
4729 if (result == L2CAP_CR_SUCCESS) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004730 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004731 set_bit(CONF_REQ_SENT, &chan->conf_state);
4732 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4733 L2CAP_CONF_REQ,
4734 l2cap_build_conf_req(chan, buf), buf);
4735 chan->num_conf_req++;
4736 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004737 }
4738}
4739
4740static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4741 u8 remote_amp_id)
4742{
4743 l2cap_move_setup(chan);
4744 chan->move_id = local_amp_id;
4745 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4746
4747 l2cap_send_move_chan_req(chan, remote_amp_id);
4748}
4749
4750static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4751{
4752 struct hci_chan *hchan = NULL;
4753
4754 /* Placeholder - get hci_chan for logical link */
4755
4756 if (hchan) {
4757 if (hchan->state == BT_CONNECTED) {
4758 /* Logical link is ready to go */
4759 chan->hs_hcon = hchan->conn;
4760 chan->hs_hcon->l2cap_data = chan->conn;
4761 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4762 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4763
4764 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4765 } else {
4766 /* Wait for logical link to be ready */
4767 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4768 }
4769 } else {
4770 /* Logical link not available */
4771 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4772 }
4773}
4774
4775static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4776{
4777 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4778 u8 rsp_result;
4779 if (result == -EINVAL)
4780 rsp_result = L2CAP_MR_BAD_ID;
4781 else
4782 rsp_result = L2CAP_MR_NOT_ALLOWED;
4783
4784 l2cap_send_move_chan_rsp(chan, rsp_result);
4785 }
4786
4787 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4788 chan->move_state = L2CAP_MOVE_STABLE;
4789
4790 /* Restart data transmission */
4791 l2cap_ertm_send(chan);
4792}
4793
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004794/* Invoke with locked chan */
4795void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004796{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004797 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004798 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004799
Mat Martineau8eb200b2012-10-23 15:24:17 -07004800 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4801 chan, result, local_amp_id, remote_amp_id);
4802
Mat Martineau8eb200b2012-10-23 15:24:17 -07004803 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4804 l2cap_chan_unlock(chan);
4805 return;
4806 }
4807
4808 if (chan->state != BT_CONNECTED) {
4809 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4810 } else if (result != L2CAP_MR_SUCCESS) {
4811 l2cap_do_move_cancel(chan, result);
4812 } else {
4813 switch (chan->move_role) {
4814 case L2CAP_MOVE_ROLE_INITIATOR:
4815 l2cap_do_move_initiate(chan, local_amp_id,
4816 remote_amp_id);
4817 break;
4818 case L2CAP_MOVE_ROLE_RESPONDER:
4819 l2cap_do_move_respond(chan, result);
4820 break;
4821 default:
4822 l2cap_do_move_cancel(chan, result);
4823 break;
4824 }
4825 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004826}
4827
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004828static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004829 struct l2cap_cmd_hdr *cmd,
4830 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004831{
4832 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004833 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004834 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004835 u16 icid = 0;
4836 u16 result = L2CAP_MR_NOT_ALLOWED;
4837
4838 if (cmd_len != sizeof(*req))
4839 return -EPROTO;
4840
4841 icid = le16_to_cpu(req->icid);
4842
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004843 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004844
Marcel Holtmann848566b2013-10-01 22:59:22 -07004845 if (!conn->hs_enabled)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004846 return -EINVAL;
4847
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004848 chan = l2cap_get_chan_by_dcid(conn, icid);
4849 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004850 rsp.icid = cpu_to_le16(icid);
4851 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4852 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4853 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004854 return 0;
4855 }
4856
Mat Martineau1500109b2012-10-23 15:24:15 -07004857 chan->ident = cmd->ident;
4858
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004859 if (chan->scid < L2CAP_CID_DYN_START ||
4860 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4861 (chan->mode != L2CAP_MODE_ERTM &&
4862 chan->mode != L2CAP_MODE_STREAMING)) {
4863 result = L2CAP_MR_NOT_ALLOWED;
4864 goto send_move_response;
4865 }
4866
4867 if (chan->local_amp_id == req->dest_amp_id) {
4868 result = L2CAP_MR_SAME_ID;
4869 goto send_move_response;
4870 }
4871
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004872 if (req->dest_amp_id != AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004873 struct hci_dev *hdev;
4874 hdev = hci_dev_get(req->dest_amp_id);
4875 if (!hdev || hdev->dev_type != HCI_AMP ||
4876 !test_bit(HCI_UP, &hdev->flags)) {
4877 if (hdev)
4878 hci_dev_put(hdev);
4879
4880 result = L2CAP_MR_BAD_ID;
4881 goto send_move_response;
4882 }
4883 hci_dev_put(hdev);
4884 }
4885
4886 /* Detect a move collision. Only send a collision response
4887 * if this side has "lost", otherwise proceed with the move.
4888 * The winner has the larger bd_addr.
4889 */
4890 if ((__chan_is_moving(chan) ||
4891 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
Marcel Holtmann6f59b902013-10-13 05:24:01 -07004892 bacmp(&conn->hcon->src, &conn->hcon->dst) > 0) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004893 result = L2CAP_MR_COLLISION;
4894 goto send_move_response;
4895 }
4896
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004897 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4898 l2cap_move_setup(chan);
4899 chan->move_id = req->dest_amp_id;
4900 icid = chan->dcid;
4901
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004902 if (req->dest_amp_id == AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004903 /* Moving to BR/EDR */
4904 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4905 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4906 result = L2CAP_MR_PEND;
4907 } else {
4908 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4909 result = L2CAP_MR_SUCCESS;
4910 }
4911 } else {
4912 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4913 /* Placeholder - uncomment when amp functions are available */
4914 /*amp_accept_physical(chan, req->dest_amp_id);*/
4915 result = L2CAP_MR_PEND;
4916 }
4917
4918send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004919 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004920
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004921 l2cap_chan_unlock(chan);
4922
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004923 return 0;
4924}
4925
Mat Martineau5b155ef2012-10-23 15:24:14 -07004926static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4927{
4928 struct l2cap_chan *chan;
4929 struct hci_chan *hchan = NULL;
4930
4931 chan = l2cap_get_chan_by_scid(conn, icid);
4932 if (!chan) {
4933 l2cap_send_move_chan_cfm_icid(conn, icid);
4934 return;
4935 }
4936
4937 __clear_chan_timer(chan);
4938 if (result == L2CAP_MR_PEND)
4939 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4940
4941 switch (chan->move_state) {
4942 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4943 /* Move confirm will be sent when logical link
4944 * is complete.
4945 */
4946 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4947 break;
4948 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4949 if (result == L2CAP_MR_PEND) {
4950 break;
4951 } else if (test_bit(CONN_LOCAL_BUSY,
4952 &chan->conn_state)) {
4953 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4954 } else {
4955 /* Logical link is up or moving to BR/EDR,
4956 * proceed with move
4957 */
4958 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4959 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4960 }
4961 break;
4962 case L2CAP_MOVE_WAIT_RSP:
4963 /* Moving to AMP */
4964 if (result == L2CAP_MR_SUCCESS) {
4965 /* Remote is ready, send confirm immediately
4966 * after logical link is ready
4967 */
4968 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4969 } else {
4970 /* Both logical link and move success
4971 * are required to confirm
4972 */
4973 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
4974 }
4975
4976 /* Placeholder - get hci_chan for logical link */
4977 if (!hchan) {
4978 /* Logical link not available */
4979 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4980 break;
4981 }
4982
4983 /* If the logical link is not yet connected, do not
4984 * send confirmation.
4985 */
4986 if (hchan->state != BT_CONNECTED)
4987 break;
4988
4989 /* Logical link is already ready to go */
4990
4991 chan->hs_hcon = hchan->conn;
4992 chan->hs_hcon->l2cap_data = chan->conn;
4993
4994 if (result == L2CAP_MR_SUCCESS) {
4995 /* Can confirm now */
4996 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4997 } else {
4998 /* Now only need move success
4999 * to confirm
5000 */
5001 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
5002 }
5003
5004 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5005 break;
5006 default:
5007 /* Any other amp move state means the move failed. */
5008 chan->move_id = chan->local_amp_id;
5009 l2cap_move_done(chan);
5010 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5011 }
5012
5013 l2cap_chan_unlock(chan);
5014}
5015
5016static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5017 u16 result)
5018{
5019 struct l2cap_chan *chan;
5020
5021 chan = l2cap_get_chan_by_ident(conn, ident);
5022 if (!chan) {
5023 /* Could not locate channel, icid is best guess */
5024 l2cap_send_move_chan_cfm_icid(conn, icid);
5025 return;
5026 }
5027
5028 __clear_chan_timer(chan);
5029
5030 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5031 if (result == L2CAP_MR_COLLISION) {
5032 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5033 } else {
5034 /* Cleanup - cancel move */
5035 chan->move_id = chan->local_amp_id;
5036 l2cap_move_done(chan);
5037 }
5038 }
5039
5040 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5041
5042 l2cap_chan_unlock(chan);
5043}
5044
5045static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5046 struct l2cap_cmd_hdr *cmd,
5047 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005048{
5049 struct l2cap_move_chan_rsp *rsp = data;
5050 u16 icid, result;
5051
5052 if (cmd_len != sizeof(*rsp))
5053 return -EPROTO;
5054
5055 icid = le16_to_cpu(rsp->icid);
5056 result = le16_to_cpu(rsp->result);
5057
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005058 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005059
Mat Martineau5b155ef2012-10-23 15:24:14 -07005060 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5061 l2cap_move_continue(conn, icid, result);
5062 else
5063 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005064
5065 return 0;
5066}
5067
Mat Martineau5f3847a2012-10-23 15:24:12 -07005068static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5069 struct l2cap_cmd_hdr *cmd,
5070 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005071{
5072 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005073 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005074 u16 icid, result;
5075
5076 if (cmd_len != sizeof(*cfm))
5077 return -EPROTO;
5078
5079 icid = le16_to_cpu(cfm->icid);
5080 result = le16_to_cpu(cfm->result);
5081
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005082 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005083
Mat Martineau5f3847a2012-10-23 15:24:12 -07005084 chan = l2cap_get_chan_by_dcid(conn, icid);
5085 if (!chan) {
5086 /* Spec requires a response even if the icid was not found */
5087 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5088 return 0;
5089 }
5090
5091 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5092 if (result == L2CAP_MC_CONFIRMED) {
5093 chan->local_amp_id = chan->move_id;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005094 if (chan->local_amp_id == AMP_ID_BREDR)
Mat Martineau5f3847a2012-10-23 15:24:12 -07005095 __release_logical_link(chan);
5096 } else {
5097 chan->move_id = chan->local_amp_id;
5098 }
5099
5100 l2cap_move_done(chan);
5101 }
5102
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005103 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5104
Mat Martineau5f3847a2012-10-23 15:24:12 -07005105 l2cap_chan_unlock(chan);
5106
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005107 return 0;
5108}
5109
5110static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005111 struct l2cap_cmd_hdr *cmd,
5112 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005113{
5114 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005115 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005116 u16 icid;
5117
5118 if (cmd_len != sizeof(*rsp))
5119 return -EPROTO;
5120
5121 icid = le16_to_cpu(rsp->icid);
5122
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005123 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005124
Mat Martineau3fd71a02012-10-23 15:24:16 -07005125 chan = l2cap_get_chan_by_scid(conn, icid);
5126 if (!chan)
5127 return 0;
5128
5129 __clear_chan_timer(chan);
5130
5131 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5132 chan->local_amp_id = chan->move_id;
5133
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005134 if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan)
Mat Martineau3fd71a02012-10-23 15:24:16 -07005135 __release_logical_link(chan);
5136
5137 l2cap_move_done(chan);
5138 }
5139
5140 l2cap_chan_unlock(chan);
5141
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005142 return 0;
5143}
5144
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005145static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005146 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005147{
5148 u16 max_latency;
5149
5150 if (min > max || min < 6 || max > 3200)
5151 return -EINVAL;
5152
5153 if (to_multiplier < 10 || to_multiplier > 3200)
5154 return -EINVAL;
5155
5156 if (max >= to_multiplier * 8)
5157 return -EINVAL;
5158
5159 max_latency = (to_multiplier * 8 / max) - 1;
5160 if (latency > 499 || latency > max_latency)
5161 return -EINVAL;
5162
5163 return 0;
5164}
5165
5166static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005167 struct l2cap_cmd_hdr *cmd,
Johan Hedberg203e6392013-05-15 10:07:15 +03005168 u16 cmd_len, u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005169{
5170 struct hci_conn *hcon = conn->hcon;
5171 struct l2cap_conn_param_update_req *req;
5172 struct l2cap_conn_param_update_rsp rsp;
Johan Hedberg203e6392013-05-15 10:07:15 +03005173 u16 min, max, latency, to_multiplier;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005174 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005175
5176 if (!(hcon->link_mode & HCI_LM_MASTER))
5177 return -EINVAL;
5178
Claudio Takahaside731152011-02-11 19:28:55 -02005179 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5180 return -EPROTO;
5181
5182 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005183 min = __le16_to_cpu(req->min);
5184 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005185 latency = __le16_to_cpu(req->latency);
5186 to_multiplier = __le16_to_cpu(req->to_multiplier);
5187
5188 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 +01005189 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005190
5191 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005192
5193 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5194 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005195 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005196 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005197 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005198
5199 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005200 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005201
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005202 if (!err)
5203 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5204
Claudio Takahaside731152011-02-11 19:28:55 -02005205 return 0;
5206}
5207
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005208static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005209 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5210 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005211{
5212 int err = 0;
5213
5214 switch (cmd->code) {
5215 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005216 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005217 break;
5218
5219 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005220 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005221 break;
5222
5223 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005224 case L2CAP_CREATE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005225 l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005226 break;
5227
5228 case L2CAP_CONF_REQ:
5229 err = l2cap_config_req(conn, cmd, cmd_len, data);
5230 break;
5231
5232 case L2CAP_CONF_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005233 l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005234 break;
5235
5236 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005237 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005238 break;
5239
5240 case L2CAP_DISCONN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005241 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005242 break;
5243
5244 case L2CAP_ECHO_REQ:
5245 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5246 break;
5247
5248 case L2CAP_ECHO_RSP:
5249 break;
5250
5251 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005252 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005253 break;
5254
5255 case L2CAP_INFO_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005256 l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005257 break;
5258
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005259 case L2CAP_CREATE_CHAN_REQ:
5260 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5261 break;
5262
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005263 case L2CAP_MOVE_CHAN_REQ:
5264 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5265 break;
5266
5267 case L2CAP_MOVE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005268 l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005269 break;
5270
5271 case L2CAP_MOVE_CHAN_CFM:
5272 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5273 break;
5274
5275 case L2CAP_MOVE_CHAN_CFM_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005276 l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005277 break;
5278
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005279 default:
5280 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5281 err = -EINVAL;
5282 break;
5283 }
5284
5285 return err;
5286}
5287
5288static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Johan Hedberg203e6392013-05-15 10:07:15 +03005289 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5290 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005291{
5292 switch (cmd->code) {
5293 case L2CAP_COMMAND_REJ:
5294 return 0;
5295
5296 case L2CAP_CONN_PARAM_UPDATE_REQ:
Johan Hedberg203e6392013-05-15 10:07:15 +03005297 return l2cap_conn_param_update_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005298
5299 case L2CAP_CONN_PARAM_UPDATE_RSP:
5300 return 0;
5301
5302 default:
5303 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5304 return -EINVAL;
5305 }
5306}
5307
Johan Hedbergc5623552013-04-29 19:35:33 +03005308static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5309 struct sk_buff *skb)
5310{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005311 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005312 struct l2cap_cmd_hdr *cmd;
5313 u16 len;
Johan Hedbergc5623552013-04-29 19:35:33 +03005314 int err;
5315
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005316 if (hcon->type != LE_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005317 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005318
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005319 if (skb->len < L2CAP_CMD_HDR_SIZE)
5320 goto drop;
Johan Hedbergc5623552013-04-29 19:35:33 +03005321
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005322 cmd = (void *) skb->data;
5323 skb_pull(skb, L2CAP_CMD_HDR_SIZE);
Johan Hedbergc5623552013-04-29 19:35:33 +03005324
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005325 len = le16_to_cpu(cmd->len);
Johan Hedbergc5623552013-04-29 19:35:33 +03005326
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005327 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, cmd->ident);
Johan Hedbergc5623552013-04-29 19:35:33 +03005328
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005329 if (len != skb->len || !cmd->ident) {
5330 BT_DBG("corrupted command");
5331 goto drop;
5332 }
Johan Hedbergc5623552013-04-29 19:35:33 +03005333
Johan Hedberg203e6392013-05-15 10:07:15 +03005334 err = l2cap_le_sig_cmd(conn, cmd, len, skb->data);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005335 if (err) {
5336 struct l2cap_cmd_rej_unk rej;
Johan Hedbergc5623552013-04-29 19:35:33 +03005337
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005338 BT_ERR("Wrong link type (%d)", err);
Johan Hedbergc5623552013-04-29 19:35:33 +03005339
Johan Hedberga5211492013-10-16 11:20:49 +03005340 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005341 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
5342 sizeof(rej), &rej);
Johan Hedbergc5623552013-04-29 19:35:33 +03005343 }
5344
Marcel Holtmann3b166292013-10-02 08:28:21 -07005345drop:
Johan Hedbergc5623552013-04-29 19:35:33 +03005346 kfree_skb(skb);
5347}
5348
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005349static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005350 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005351{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005352 struct hci_conn *hcon = conn->hcon;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005353 u8 *data = skb->data;
5354 int len = skb->len;
5355 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005356 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005357
5358 l2cap_raw_recv(conn, skb);
5359
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005360 if (hcon->type != ACL_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005361 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005362
Linus Torvalds1da177e2005-04-16 15:20:36 -07005363 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005364 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005365 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5366 data += L2CAP_CMD_HDR_SIZE;
5367 len -= L2CAP_CMD_HDR_SIZE;
5368
Al Viro88219a02007-07-29 00:17:25 -07005369 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005370
Gustavo Padovan2d792812012-10-06 10:07:01 +01005371 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5372 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005373
Al Viro88219a02007-07-29 00:17:25 -07005374 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005375 BT_DBG("corrupted command");
5376 break;
5377 }
5378
Johan Hedbergc5623552013-04-29 19:35:33 +03005379 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005380 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005381 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005382
5383 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005384
Johan Hedberga5211492013-10-16 11:20:49 +03005385 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005386 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5387 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005388 }
5389
Al Viro88219a02007-07-29 00:17:25 -07005390 data += cmd_len;
5391 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005392 }
5393
Marcel Holtmann3b166292013-10-02 08:28:21 -07005394drop:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005395 kfree_skb(skb);
5396}
5397
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005398static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005399{
5400 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005401 int hdr_size;
5402
5403 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5404 hdr_size = L2CAP_EXT_HDR_SIZE;
5405 else
5406 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005407
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005408 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005409 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005410 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5411 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5412
5413 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005414 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005415 }
5416 return 0;
5417}
5418
Mat Martineau6ea00482012-05-17 20:53:52 -07005419static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005420{
Mat Martineaue31f7632012-05-17 20:53:41 -07005421 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005422
Mat Martineaue31f7632012-05-17 20:53:41 -07005423 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005424
Mat Martineaue31f7632012-05-17 20:53:41 -07005425 memset(&control, 0, sizeof(control));
5426 control.sframe = 1;
5427 control.final = 1;
5428 control.reqseq = chan->buffer_seq;
5429 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005430
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005431 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005432 control.super = L2CAP_SUPER_RNR;
5433 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005434 }
5435
Mat Martineaue31f7632012-05-17 20:53:41 -07005436 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5437 chan->unacked_frames > 0)
5438 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005439
Mat Martineaue31f7632012-05-17 20:53:41 -07005440 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005441 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005442
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005443 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005444 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5445 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5446 * send it now.
5447 */
5448 control.super = L2CAP_SUPER_RR;
5449 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005450 }
5451}
5452
Gustavo Padovan2d792812012-10-06 10:07:01 +01005453static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5454 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005455{
Mat Martineau84084a32011-07-22 14:54:00 -07005456 /* skb->len reflects data in skb as well as all fragments
5457 * skb->data_len reflects only data in fragments
5458 */
5459 if (!skb_has_frag_list(skb))
5460 skb_shinfo(skb)->frag_list = new_frag;
5461
5462 new_frag->next = NULL;
5463
5464 (*last_frag)->next = new_frag;
5465 *last_frag = new_frag;
5466
5467 skb->len += new_frag->len;
5468 skb->data_len += new_frag->len;
5469 skb->truesize += new_frag->truesize;
5470}
5471
Mat Martineau4b51dae92012-05-17 20:53:37 -07005472static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5473 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005474{
5475 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005476
Mat Martineau4b51dae92012-05-17 20:53:37 -07005477 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005478 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005479 if (chan->sdu)
5480 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005481
Gustavo Padovan80b98022012-05-27 22:27:51 -03005482 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005483 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005484
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005485 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005486 if (chan->sdu)
5487 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005488
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005489 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005490 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005491
Mat Martineau84084a32011-07-22 14:54:00 -07005492 if (chan->sdu_len > chan->imtu) {
5493 err = -EMSGSIZE;
5494 break;
5495 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005496
Mat Martineau84084a32011-07-22 14:54:00 -07005497 if (skb->len >= chan->sdu_len)
5498 break;
5499
5500 chan->sdu = skb;
5501 chan->sdu_last_frag = skb;
5502
5503 skb = NULL;
5504 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005505 break;
5506
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005507 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005508 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005509 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005510
Mat Martineau84084a32011-07-22 14:54:00 -07005511 append_skb_frag(chan->sdu, skb,
5512 &chan->sdu_last_frag);
5513 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005514
Mat Martineau84084a32011-07-22 14:54:00 -07005515 if (chan->sdu->len >= chan->sdu_len)
5516 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005517
Mat Martineau84084a32011-07-22 14:54:00 -07005518 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005519 break;
5520
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005521 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005522 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005523 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005524
Mat Martineau84084a32011-07-22 14:54:00 -07005525 append_skb_frag(chan->sdu, skb,
5526 &chan->sdu_last_frag);
5527 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005528
Mat Martineau84084a32011-07-22 14:54:00 -07005529 if (chan->sdu->len != chan->sdu_len)
5530 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005531
Gustavo Padovan80b98022012-05-27 22:27:51 -03005532 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005533
Mat Martineau84084a32011-07-22 14:54:00 -07005534 if (!err) {
5535 /* Reassembly complete */
5536 chan->sdu = NULL;
5537 chan->sdu_last_frag = NULL;
5538 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005539 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005540 break;
5541 }
5542
Mat Martineau84084a32011-07-22 14:54:00 -07005543 if (err) {
5544 kfree_skb(skb);
5545 kfree_skb(chan->sdu);
5546 chan->sdu = NULL;
5547 chan->sdu_last_frag = NULL;
5548 chan->sdu_len = 0;
5549 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005550
Mat Martineau84084a32011-07-22 14:54:00 -07005551 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005552}
5553
Mat Martineau32b32732012-10-23 15:24:11 -07005554static int l2cap_resegment(struct l2cap_chan *chan)
5555{
5556 /* Placeholder */
5557 return 0;
5558}
5559
Mat Martineaue3281402011-07-07 09:39:02 -07005560void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132eb2010-06-21 19:39:50 -03005561{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005562 u8 event;
5563
5564 if (chan->mode != L2CAP_MODE_ERTM)
5565 return;
5566
5567 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005568 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005569}
5570
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005571static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5572{
Mat Martineau63838722012-05-17 20:53:45 -07005573 int err = 0;
5574 /* Pass sequential frames to l2cap_reassemble_sdu()
5575 * until a gap is encountered.
5576 */
5577
5578 BT_DBG("chan %p", chan);
5579
5580 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5581 struct sk_buff *skb;
5582 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5583 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5584
5585 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5586
5587 if (!skb)
5588 break;
5589
5590 skb_unlink(skb, &chan->srej_q);
5591 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5592 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5593 if (err)
5594 break;
5595 }
5596
5597 if (skb_queue_empty(&chan->srej_q)) {
5598 chan->rx_state = L2CAP_RX_STATE_RECV;
5599 l2cap_send_ack(chan);
5600 }
5601
5602 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005603}
5604
5605static void l2cap_handle_srej(struct l2cap_chan *chan,
5606 struct l2cap_ctrl *control)
5607{
Mat Martineauf80842a2012-05-17 20:53:46 -07005608 struct sk_buff *skb;
5609
5610 BT_DBG("chan %p, control %p", chan, control);
5611
5612 if (control->reqseq == chan->next_tx_seq) {
5613 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005614 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005615 return;
5616 }
5617
5618 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5619
5620 if (skb == NULL) {
5621 BT_DBG("Seq %d not available for retransmission",
5622 control->reqseq);
5623 return;
5624 }
5625
5626 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5627 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005628 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005629 return;
5630 }
5631
5632 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5633
5634 if (control->poll) {
5635 l2cap_pass_to_tx(chan, control);
5636
5637 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5638 l2cap_retransmit(chan, control);
5639 l2cap_ertm_send(chan);
5640
5641 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5642 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5643 chan->srej_save_reqseq = control->reqseq;
5644 }
5645 } else {
5646 l2cap_pass_to_tx_fbit(chan, control);
5647
5648 if (control->final) {
5649 if (chan->srej_save_reqseq != control->reqseq ||
5650 !test_and_clear_bit(CONN_SREJ_ACT,
5651 &chan->conn_state))
5652 l2cap_retransmit(chan, control);
5653 } else {
5654 l2cap_retransmit(chan, control);
5655 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5656 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5657 chan->srej_save_reqseq = control->reqseq;
5658 }
5659 }
5660 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005661}
5662
5663static void l2cap_handle_rej(struct l2cap_chan *chan,
5664 struct l2cap_ctrl *control)
5665{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005666 struct sk_buff *skb;
5667
5668 BT_DBG("chan %p, control %p", chan, control);
5669
5670 if (control->reqseq == chan->next_tx_seq) {
5671 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005672 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005673 return;
5674 }
5675
5676 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5677
5678 if (chan->max_tx && skb &&
5679 bt_cb(skb)->control.retries >= chan->max_tx) {
5680 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005681 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005682 return;
5683 }
5684
5685 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5686
5687 l2cap_pass_to_tx(chan, control);
5688
5689 if (control->final) {
5690 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5691 l2cap_retransmit_all(chan, control);
5692 } else {
5693 l2cap_retransmit_all(chan, control);
5694 l2cap_ertm_send(chan);
5695 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5696 set_bit(CONN_REJ_ACT, &chan->conn_state);
5697 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005698}
5699
Mat Martineau4b51dae92012-05-17 20:53:37 -07005700static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5701{
5702 BT_DBG("chan %p, txseq %d", chan, txseq);
5703
5704 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5705 chan->expected_tx_seq);
5706
5707 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5708 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005709 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005710 /* See notes below regarding "double poll" and
5711 * invalid packets.
5712 */
5713 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5714 BT_DBG("Invalid/Ignore - after SREJ");
5715 return L2CAP_TXSEQ_INVALID_IGNORE;
5716 } else {
5717 BT_DBG("Invalid - in window after SREJ sent");
5718 return L2CAP_TXSEQ_INVALID;
5719 }
5720 }
5721
5722 if (chan->srej_list.head == txseq) {
5723 BT_DBG("Expected SREJ");
5724 return L2CAP_TXSEQ_EXPECTED_SREJ;
5725 }
5726
5727 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5728 BT_DBG("Duplicate SREJ - txseq already stored");
5729 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5730 }
5731
5732 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5733 BT_DBG("Unexpected SREJ - not requested");
5734 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5735 }
5736 }
5737
5738 if (chan->expected_tx_seq == txseq) {
5739 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5740 chan->tx_win) {
5741 BT_DBG("Invalid - txseq outside tx window");
5742 return L2CAP_TXSEQ_INVALID;
5743 } else {
5744 BT_DBG("Expected");
5745 return L2CAP_TXSEQ_EXPECTED;
5746 }
5747 }
5748
5749 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01005750 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005751 BT_DBG("Duplicate - expected_tx_seq later than txseq");
5752 return L2CAP_TXSEQ_DUPLICATE;
5753 }
5754
5755 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
5756 /* A source of invalid packets is a "double poll" condition,
5757 * where delays cause us to send multiple poll packets. If
5758 * the remote stack receives and processes both polls,
5759 * sequence numbers can wrap around in such a way that a
5760 * resent frame has a sequence number that looks like new data
5761 * with a sequence gap. This would trigger an erroneous SREJ
5762 * request.
5763 *
5764 * Fortunately, this is impossible with a tx window that's
5765 * less than half of the maximum sequence number, which allows
5766 * invalid frames to be safely ignored.
5767 *
5768 * With tx window sizes greater than half of the tx window
5769 * maximum, the frame is invalid and cannot be ignored. This
5770 * causes a disconnect.
5771 */
5772
5773 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5774 BT_DBG("Invalid/Ignore - txseq outside tx window");
5775 return L2CAP_TXSEQ_INVALID_IGNORE;
5776 } else {
5777 BT_DBG("Invalid - txseq outside tx window");
5778 return L2CAP_TXSEQ_INVALID;
5779 }
5780 } else {
5781 BT_DBG("Unexpected - txseq indicates missing frames");
5782 return L2CAP_TXSEQ_UNEXPECTED;
5783 }
5784}
5785
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005786static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5787 struct l2cap_ctrl *control,
5788 struct sk_buff *skb, u8 event)
5789{
5790 int err = 0;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005791 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005792
5793 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5794 event);
5795
5796 switch (event) {
5797 case L2CAP_EV_RECV_IFRAME:
5798 switch (l2cap_classify_txseq(chan, control->txseq)) {
5799 case L2CAP_TXSEQ_EXPECTED:
5800 l2cap_pass_to_tx(chan, control);
5801
5802 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5803 BT_DBG("Busy, discarding expected seq %d",
5804 control->txseq);
5805 break;
5806 }
5807
5808 chan->expected_tx_seq = __next_seq(chan,
5809 control->txseq);
5810
5811 chan->buffer_seq = chan->expected_tx_seq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005812 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005813
5814 err = l2cap_reassemble_sdu(chan, skb, control);
5815 if (err)
5816 break;
5817
5818 if (control->final) {
5819 if (!test_and_clear_bit(CONN_REJ_ACT,
5820 &chan->conn_state)) {
5821 control->final = 0;
5822 l2cap_retransmit_all(chan, control);
5823 l2cap_ertm_send(chan);
5824 }
5825 }
5826
5827 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5828 l2cap_send_ack(chan);
5829 break;
5830 case L2CAP_TXSEQ_UNEXPECTED:
5831 l2cap_pass_to_tx(chan, control);
5832
5833 /* Can't issue SREJ frames in the local busy state.
5834 * Drop this frame, it will be seen as missing
5835 * when local busy is exited.
5836 */
5837 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5838 BT_DBG("Busy, discarding unexpected seq %d",
5839 control->txseq);
5840 break;
5841 }
5842
5843 /* There was a gap in the sequence, so an SREJ
5844 * must be sent for each missing frame. The
5845 * current frame is stored for later use.
5846 */
5847 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005848 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005849 BT_DBG("Queued %p (queue len %d)", skb,
5850 skb_queue_len(&chan->srej_q));
5851
5852 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5853 l2cap_seq_list_clear(&chan->srej_list);
5854 l2cap_send_srej(chan, control->txseq);
5855
5856 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5857 break;
5858 case L2CAP_TXSEQ_DUPLICATE:
5859 l2cap_pass_to_tx(chan, control);
5860 break;
5861 case L2CAP_TXSEQ_INVALID_IGNORE:
5862 break;
5863 case L2CAP_TXSEQ_INVALID:
5864 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005865 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005866 break;
5867 }
5868 break;
5869 case L2CAP_EV_RECV_RR:
5870 l2cap_pass_to_tx(chan, control);
5871 if (control->final) {
5872 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5873
Mat Martineaue6a3ee62012-10-23 15:24:22 -07005874 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
5875 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005876 control->final = 0;
5877 l2cap_retransmit_all(chan, control);
5878 }
5879
5880 l2cap_ertm_send(chan);
5881 } else if (control->poll) {
5882 l2cap_send_i_or_rr_or_rnr(chan);
5883 } else {
5884 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5885 &chan->conn_state) &&
5886 chan->unacked_frames)
5887 __set_retrans_timer(chan);
5888
5889 l2cap_ertm_send(chan);
5890 }
5891 break;
5892 case L2CAP_EV_RECV_RNR:
5893 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5894 l2cap_pass_to_tx(chan, control);
5895 if (control && control->poll) {
5896 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5897 l2cap_send_rr_or_rnr(chan, 0);
5898 }
5899 __clear_retrans_timer(chan);
5900 l2cap_seq_list_clear(&chan->retrans_list);
5901 break;
5902 case L2CAP_EV_RECV_REJ:
5903 l2cap_handle_rej(chan, control);
5904 break;
5905 case L2CAP_EV_RECV_SREJ:
5906 l2cap_handle_srej(chan, control);
5907 break;
5908 default:
5909 break;
5910 }
5911
5912 if (skb && !skb_in_use) {
5913 BT_DBG("Freeing %p", skb);
5914 kfree_skb(skb);
5915 }
5916
5917 return err;
5918}
5919
5920static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5921 struct l2cap_ctrl *control,
5922 struct sk_buff *skb, u8 event)
5923{
5924 int err = 0;
5925 u16 txseq = control->txseq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005926 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005927
5928 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5929 event);
5930
5931 switch (event) {
5932 case L2CAP_EV_RECV_IFRAME:
5933 switch (l2cap_classify_txseq(chan, txseq)) {
5934 case L2CAP_TXSEQ_EXPECTED:
5935 /* Keep frame for reassembly later */
5936 l2cap_pass_to_tx(chan, control);
5937 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005938 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005939 BT_DBG("Queued %p (queue len %d)", skb,
5940 skb_queue_len(&chan->srej_q));
5941
5942 chan->expected_tx_seq = __next_seq(chan, txseq);
5943 break;
5944 case L2CAP_TXSEQ_EXPECTED_SREJ:
5945 l2cap_seq_list_pop(&chan->srej_list);
5946
5947 l2cap_pass_to_tx(chan, control);
5948 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005949 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005950 BT_DBG("Queued %p (queue len %d)", skb,
5951 skb_queue_len(&chan->srej_q));
5952
5953 err = l2cap_rx_queued_iframes(chan);
5954 if (err)
5955 break;
5956
5957 break;
5958 case L2CAP_TXSEQ_UNEXPECTED:
5959 /* Got a frame that can't be reassembled yet.
5960 * Save it for later, and send SREJs to cover
5961 * the missing frames.
5962 */
5963 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005964 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005965 BT_DBG("Queued %p (queue len %d)", skb,
5966 skb_queue_len(&chan->srej_q));
5967
5968 l2cap_pass_to_tx(chan, control);
5969 l2cap_send_srej(chan, control->txseq);
5970 break;
5971 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
5972 /* This frame was requested with an SREJ, but
5973 * some expected retransmitted frames are
5974 * missing. Request retransmission of missing
5975 * SREJ'd frames.
5976 */
5977 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005978 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005979 BT_DBG("Queued %p (queue len %d)", skb,
5980 skb_queue_len(&chan->srej_q));
5981
5982 l2cap_pass_to_tx(chan, control);
5983 l2cap_send_srej_list(chan, control->txseq);
5984 break;
5985 case L2CAP_TXSEQ_DUPLICATE_SREJ:
5986 /* We've already queued this frame. Drop this copy. */
5987 l2cap_pass_to_tx(chan, control);
5988 break;
5989 case L2CAP_TXSEQ_DUPLICATE:
5990 /* Expecting a later sequence number, so this frame
5991 * was already received. Ignore it completely.
5992 */
5993 break;
5994 case L2CAP_TXSEQ_INVALID_IGNORE:
5995 break;
5996 case L2CAP_TXSEQ_INVALID:
5997 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005998 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005999 break;
6000 }
6001 break;
6002 case L2CAP_EV_RECV_RR:
6003 l2cap_pass_to_tx(chan, control);
6004 if (control->final) {
6005 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6006
6007 if (!test_and_clear_bit(CONN_REJ_ACT,
6008 &chan->conn_state)) {
6009 control->final = 0;
6010 l2cap_retransmit_all(chan, control);
6011 }
6012
6013 l2cap_ertm_send(chan);
6014 } else if (control->poll) {
6015 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6016 &chan->conn_state) &&
6017 chan->unacked_frames) {
6018 __set_retrans_timer(chan);
6019 }
6020
6021 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6022 l2cap_send_srej_tail(chan);
6023 } else {
6024 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6025 &chan->conn_state) &&
6026 chan->unacked_frames)
6027 __set_retrans_timer(chan);
6028
6029 l2cap_send_ack(chan);
6030 }
6031 break;
6032 case L2CAP_EV_RECV_RNR:
6033 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6034 l2cap_pass_to_tx(chan, control);
6035 if (control->poll) {
6036 l2cap_send_srej_tail(chan);
6037 } else {
6038 struct l2cap_ctrl rr_control;
6039 memset(&rr_control, 0, sizeof(rr_control));
6040 rr_control.sframe = 1;
6041 rr_control.super = L2CAP_SUPER_RR;
6042 rr_control.reqseq = chan->buffer_seq;
6043 l2cap_send_sframe(chan, &rr_control);
6044 }
6045
6046 break;
6047 case L2CAP_EV_RECV_REJ:
6048 l2cap_handle_rej(chan, control);
6049 break;
6050 case L2CAP_EV_RECV_SREJ:
6051 l2cap_handle_srej(chan, control);
6052 break;
6053 }
6054
6055 if (skb && !skb_in_use) {
6056 BT_DBG("Freeing %p", skb);
6057 kfree_skb(skb);
6058 }
6059
6060 return err;
6061}
6062
Mat Martineau32b32732012-10-23 15:24:11 -07006063static int l2cap_finish_move(struct l2cap_chan *chan)
6064{
6065 BT_DBG("chan %p", chan);
6066
6067 chan->rx_state = L2CAP_RX_STATE_RECV;
6068
6069 if (chan->hs_hcon)
6070 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6071 else
6072 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6073
6074 return l2cap_resegment(chan);
6075}
6076
6077static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6078 struct l2cap_ctrl *control,
6079 struct sk_buff *skb, u8 event)
6080{
6081 int err;
6082
6083 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6084 event);
6085
6086 if (!control->poll)
6087 return -EPROTO;
6088
6089 l2cap_process_reqseq(chan, control->reqseq);
6090
6091 if (!skb_queue_empty(&chan->tx_q))
6092 chan->tx_send_head = skb_peek(&chan->tx_q);
6093 else
6094 chan->tx_send_head = NULL;
6095
6096 /* Rewind next_tx_seq to the point expected
6097 * by the receiver.
6098 */
6099 chan->next_tx_seq = control->reqseq;
6100 chan->unacked_frames = 0;
6101
6102 err = l2cap_finish_move(chan);
6103 if (err)
6104 return err;
6105
6106 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6107 l2cap_send_i_or_rr_or_rnr(chan);
6108
6109 if (event == L2CAP_EV_RECV_IFRAME)
6110 return -EPROTO;
6111
6112 return l2cap_rx_state_recv(chan, control, NULL, event);
6113}
6114
6115static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6116 struct l2cap_ctrl *control,
6117 struct sk_buff *skb, u8 event)
6118{
6119 int err;
6120
6121 if (!control->final)
6122 return -EPROTO;
6123
6124 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6125
6126 chan->rx_state = L2CAP_RX_STATE_RECV;
6127 l2cap_process_reqseq(chan, control->reqseq);
6128
6129 if (!skb_queue_empty(&chan->tx_q))
6130 chan->tx_send_head = skb_peek(&chan->tx_q);
6131 else
6132 chan->tx_send_head = NULL;
6133
6134 /* Rewind next_tx_seq to the point expected
6135 * by the receiver.
6136 */
6137 chan->next_tx_seq = control->reqseq;
6138 chan->unacked_frames = 0;
6139
6140 if (chan->hs_hcon)
6141 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6142 else
6143 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6144
6145 err = l2cap_resegment(chan);
6146
6147 if (!err)
6148 err = l2cap_rx_state_recv(chan, control, skb, event);
6149
6150 return err;
6151}
6152
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006153static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6154{
6155 /* Make sure reqseq is for a packet that has been sent but not acked */
6156 u16 unacked;
6157
6158 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6159 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6160}
6161
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006162static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6163 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006164{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006165 int err = 0;
6166
6167 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6168 control, skb, event, chan->rx_state);
6169
6170 if (__valid_reqseq(chan, control->reqseq)) {
6171 switch (chan->rx_state) {
6172 case L2CAP_RX_STATE_RECV:
6173 err = l2cap_rx_state_recv(chan, control, skb, event);
6174 break;
6175 case L2CAP_RX_STATE_SREJ_SENT:
6176 err = l2cap_rx_state_srej_sent(chan, control, skb,
6177 event);
6178 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006179 case L2CAP_RX_STATE_WAIT_P:
6180 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6181 break;
6182 case L2CAP_RX_STATE_WAIT_F:
6183 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6184 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006185 default:
6186 /* shut it down */
6187 break;
6188 }
6189 } else {
6190 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6191 control->reqseq, chan->next_tx_seq,
6192 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006193 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006194 }
6195
6196 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006197}
6198
6199static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6200 struct sk_buff *skb)
6201{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006202 int err = 0;
6203
6204 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6205 chan->rx_state);
6206
6207 if (l2cap_classify_txseq(chan, control->txseq) ==
6208 L2CAP_TXSEQ_EXPECTED) {
6209 l2cap_pass_to_tx(chan, control);
6210
6211 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6212 __next_seq(chan, chan->buffer_seq));
6213
6214 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6215
6216 l2cap_reassemble_sdu(chan, skb, control);
6217 } else {
6218 if (chan->sdu) {
6219 kfree_skb(chan->sdu);
6220 chan->sdu = NULL;
6221 }
6222 chan->sdu_last_frag = NULL;
6223 chan->sdu_len = 0;
6224
6225 if (skb) {
6226 BT_DBG("Freeing %p", skb);
6227 kfree_skb(skb);
6228 }
6229 }
6230
6231 chan->last_acked_seq = control->txseq;
6232 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6233
6234 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006235}
6236
6237static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6238{
6239 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6240 u16 len;
6241 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006242
Mat Martineaub76bbd62012-04-11 10:48:43 -07006243 __unpack_control(chan, skb);
6244
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006245 len = skb->len;
6246
6247 /*
6248 * We can just drop the corrupted I-frame here.
6249 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006250 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006251 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006252 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006253 goto drop;
6254
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006255 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006256 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006257
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006258 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006259 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006260
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006261 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006262 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006263 goto drop;
6264 }
6265
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006266 if (!control->sframe) {
6267 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006268
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006269 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6270 control->sar, control->reqseq, control->final,
6271 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006272
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006273 /* Validate F-bit - F=0 always valid, F=1 only
6274 * valid in TX WAIT_F
6275 */
6276 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006277 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006278
6279 if (chan->mode != L2CAP_MODE_STREAMING) {
6280 event = L2CAP_EV_RECV_IFRAME;
6281 err = l2cap_rx(chan, control, skb, event);
6282 } else {
6283 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006284 }
6285
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006286 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006287 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006288 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006289 const u8 rx_func_to_event[4] = {
6290 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6291 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6292 };
6293
6294 /* Only I-frames are expected in streaming mode */
6295 if (chan->mode == L2CAP_MODE_STREAMING)
6296 goto drop;
6297
6298 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6299 control->reqseq, control->final, control->poll,
6300 control->super);
6301
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006302 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006303 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006304 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006305 goto drop;
6306 }
6307
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006308 /* Validate F and P bits */
6309 if (control->final && (control->poll ||
6310 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6311 goto drop;
6312
6313 event = rx_func_to_event[control->super];
6314 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006315 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006316 }
6317
6318 return 0;
6319
6320drop:
6321 kfree_skb(skb);
6322 return 0;
6323}
6324
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006325static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6326 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006327{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006328 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006329
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006330 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006331 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006332 if (cid == L2CAP_CID_A2MP) {
6333 chan = a2mp_channel_create(conn, skb);
6334 if (!chan) {
6335 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006336 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006337 }
6338
6339 l2cap_chan_lock(chan);
6340 } else {
6341 BT_DBG("unknown cid 0x%4.4x", cid);
6342 /* Drop packet and return */
6343 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006344 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006345 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006346 }
6347
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006348 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006349
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006350 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006351 goto drop;
6352
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006353 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006354 case L2CAP_MODE_BASIC:
6355 /* If socket recv buffers overflows we drop data here
6356 * which is *bad* because L2CAP has to be reliable.
6357 * But we don't have any other choice. L2CAP doesn't
6358 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006359
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006360 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006361 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006362
Gustavo Padovan80b98022012-05-27 22:27:51 -03006363 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006364 goto done;
6365 break;
6366
6367 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006368 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006369 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006370 goto done;
6371
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006372 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006373 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006374 break;
6375 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006376
6377drop:
6378 kfree_skb(skb);
6379
6380done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006381 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006382}
6383
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006384static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6385 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006386{
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006387 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006388 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006389
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006390 if (hcon->type != ACL_LINK)
6391 goto drop;
6392
Johan Hedbergbf20fd42013-05-14 13:23:13 +03006393 chan = l2cap_global_chan_by_psm(0, psm, &hcon->src, &hcon->dst,
6394 ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006395 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006396 goto drop;
6397
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006398 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006399
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006400 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006401 goto drop;
6402
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006403 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006404 goto drop;
6405
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006406 /* Store remote BD_ADDR and PSM for msg_name */
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006407 bacpy(&bt_cb(skb)->bdaddr, &hcon->dst);
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006408 bt_cb(skb)->psm = psm;
6409
Gustavo Padovan80b98022012-05-27 22:27:51 -03006410 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006411 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006412
6413drop:
6414 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006415}
6416
Marcel Holtmann72f78352013-04-23 00:59:00 -07006417static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006418 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006419{
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006420 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006421 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006422
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006423 if (hcon->type != LE_LINK)
6424 goto drop;
6425
Johan Hedbergaf1c0132013-04-29 19:35:42 +03006426 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006427 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006428 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006429 goto drop;
6430
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006431 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006432
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07006433 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, hcon->dst_type))
6434 goto drop;
6435
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006436 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006437 goto drop;
6438
Gustavo Padovan80b98022012-05-27 22:27:51 -03006439 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006440 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006441
6442drop:
6443 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006444}
6445
Linus Torvalds1da177e2005-04-16 15:20:36 -07006446static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6447{
6448 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006449 u16 cid, len;
6450 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006451
6452 skb_pull(skb, L2CAP_HDR_SIZE);
6453 cid = __le16_to_cpu(lh->cid);
6454 len = __le16_to_cpu(lh->len);
6455
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006456 if (len != skb->len) {
6457 kfree_skb(skb);
6458 return;
6459 }
6460
Linus Torvalds1da177e2005-04-16 15:20:36 -07006461 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6462
6463 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006464 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006465 l2cap_sig_channel(conn, skb);
6466 break;
6467
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006468 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006469 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006470 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006471 l2cap_conless_channel(conn, psm, skb);
6472 break;
6473
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006474 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006475 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006476 break;
6477
Marcel Holtmanna2877622013-10-02 23:46:54 -07006478 case L2CAP_CID_LE_SIGNALING:
6479 l2cap_le_sig_channel(conn, skb);
6480 break;
6481
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006482 case L2CAP_CID_SMP:
6483 if (smp_sig_channel(conn, skb))
6484 l2cap_conn_del(conn->hcon, EACCES);
6485 break;
6486
Linus Torvalds1da177e2005-04-16 15:20:36 -07006487 default:
6488 l2cap_data_channel(conn, cid, skb);
6489 break;
6490 }
6491}
6492
6493/* ---- L2CAP interface with lower layer (HCI) ---- */
6494
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006495int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006496{
6497 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006498 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006499
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006500 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006501
6502 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006503 read_lock(&chan_list_lock);
6504 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006505 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006506 continue;
6507
Marcel Holtmann7eafc592013-10-13 08:12:47 -07006508 if (!bacmp(&c->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006509 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006510 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006511 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006512 exact++;
Marcel Holtmann7eafc592013-10-13 08:12:47 -07006513 } else if (!bacmp(&c->src, BDADDR_ANY)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006514 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006515 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006516 lm2 |= HCI_LM_MASTER;
6517 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006518 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006519 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006520
6521 return exact ? lm1 : lm2;
6522}
6523
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006524void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006525{
Marcel Holtmann01394182006-07-03 10:02:46 +02006526 struct l2cap_conn *conn;
6527
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006528 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006529
Linus Torvalds1da177e2005-04-16 15:20:36 -07006530 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03006531 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006532 if (conn)
6533 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006534 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006535 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006536 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006537}
6538
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006539int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006540{
6541 struct l2cap_conn *conn = hcon->l2cap_data;
6542
6543 BT_DBG("hcon %p", hcon);
6544
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006545 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006546 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006547 return conn->disc_reason;
6548}
6549
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006550void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006551{
6552 BT_DBG("hcon %p reason %d", hcon, reason);
6553
Joe Perchese1750722011-06-29 18:18:29 -07006554 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006555}
6556
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006557static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006558{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006559 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006560 return;
6561
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006562 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006563 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006564 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006565 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006566 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006567 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006568 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006569 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006570 }
6571}
6572
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006573int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006574{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006575 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006576 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006577
Marcel Holtmann01394182006-07-03 10:02:46 +02006578 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006579 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006580
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006581 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006582
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006583 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306584 if (!status && encrypt)
6585 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006586 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006587 }
6588
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006589 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006590
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006591 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006592 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006593
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006594 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6595 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006596
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006597 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6598 l2cap_chan_unlock(chan);
6599 continue;
6600 }
6601
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006602 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006603 if (!status && encrypt) {
6604 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006605 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006606 }
6607
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006608 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006609 continue;
6610 }
6611
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006612 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006613 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006614 continue;
6615 }
6616
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006617 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006618 chan->state == BT_CONFIG)) {
Marcel Holtmannd97c8992013-10-14 02:53:54 -07006619 chan->ops->resume(chan);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006620 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006621 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006622 continue;
6623 }
6624
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006625 if (chan->state == BT_CONNECT) {
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02006626 if (!status)
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006627 l2cap_start_connection(chan);
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02006628 else
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006629 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006630 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006631 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006632 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006633
6634 if (!status) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07006635 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006636 res = L2CAP_CR_PEND;
6637 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006638 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006639 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02006640 l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006641 res = L2CAP_CR_SUCCESS;
6642 stat = L2CAP_CS_NO_INFO;
6643 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006644 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02006645 l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006646 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006647 res = L2CAP_CR_SEC_BLOCK;
6648 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006649 }
6650
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006651 rsp.scid = cpu_to_le16(chan->dcid);
6652 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006653 rsp.result = cpu_to_le16(res);
6654 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006655 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006656 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006657
6658 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6659 res == L2CAP_CR_SUCCESS) {
6660 char buf[128];
6661 set_bit(CONF_REQ_SENT, &chan->conf_state);
6662 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6663 L2CAP_CONF_REQ,
6664 l2cap_build_conf_req(chan, buf),
6665 buf);
6666 chan->num_conf_req++;
6667 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006668 }
6669
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006670 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006671 }
6672
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006673 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006674
Linus Torvalds1da177e2005-04-16 15:20:36 -07006675 return 0;
6676}
6677
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006678int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006679{
6680 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006681 struct l2cap_hdr *hdr;
6682 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006683
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006684 /* For AMP controller do not create l2cap conn */
6685 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6686 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006687
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006688 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03006689 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006690
6691 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006692 goto drop;
6693
6694 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6695
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006696 switch (flags) {
6697 case ACL_START:
6698 case ACL_START_NO_FLUSH:
6699 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006700 if (conn->rx_len) {
6701 BT_ERR("Unexpected start frame (len %d)", skb->len);
6702 kfree_skb(conn->rx_skb);
6703 conn->rx_skb = NULL;
6704 conn->rx_len = 0;
6705 l2cap_conn_unreliable(conn, ECOMM);
6706 }
6707
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006708 /* Start fragment always begin with Basic L2CAP header */
6709 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006710 BT_ERR("Frame is too short (len %d)", skb->len);
6711 l2cap_conn_unreliable(conn, ECOMM);
6712 goto drop;
6713 }
6714
6715 hdr = (struct l2cap_hdr *) skb->data;
6716 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6717
6718 if (len == skb->len) {
6719 /* Complete frame received */
6720 l2cap_recv_frame(conn, skb);
6721 return 0;
6722 }
6723
6724 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6725
6726 if (skb->len > len) {
6727 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006728 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006729 l2cap_conn_unreliable(conn, ECOMM);
6730 goto drop;
6731 }
6732
6733 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006734 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006735 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006736 goto drop;
6737
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006738 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006739 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006740 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006741 break;
6742
6743 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006744 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6745
6746 if (!conn->rx_len) {
6747 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6748 l2cap_conn_unreliable(conn, ECOMM);
6749 goto drop;
6750 }
6751
6752 if (skb->len > conn->rx_len) {
6753 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006754 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006755 kfree_skb(conn->rx_skb);
6756 conn->rx_skb = NULL;
6757 conn->rx_len = 0;
6758 l2cap_conn_unreliable(conn, ECOMM);
6759 goto drop;
6760 }
6761
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006762 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006763 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006764 conn->rx_len -= skb->len;
6765
6766 if (!conn->rx_len) {
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02006767 /* Complete frame received. l2cap_recv_frame
6768 * takes ownership of the skb so set the global
6769 * rx_skb pointer to NULL first.
6770 */
6771 struct sk_buff *rx_skb = conn->rx_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006772 conn->rx_skb = NULL;
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02006773 l2cap_recv_frame(conn, rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006774 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006775 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006776 }
6777
6778drop:
6779 kfree_skb(skb);
6780 return 0;
6781}
6782
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006783static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006784{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006785 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006786
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006787 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006788
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006789 list_for_each_entry(c, &chan_list, global_l) {
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006790 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 -07006791 &c->src, &c->dst,
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006792 c->state, __le16_to_cpu(c->psm),
6793 c->scid, c->dcid, c->imtu, c->omtu,
6794 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006795 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006796
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006797 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006798
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006799 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006800}
6801
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006802static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6803{
6804 return single_open(file, l2cap_debugfs_show, inode->i_private);
6805}
6806
6807static const struct file_operations l2cap_debugfs_fops = {
6808 .open = l2cap_debugfs_open,
6809 .read = seq_read,
6810 .llseek = seq_lseek,
6811 .release = single_release,
6812};
6813
6814static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006815
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006816int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006817{
6818 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006819
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006820 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006821 if (err < 0)
6822 return err;
6823
Marcel Holtmann1120e4b2013-10-17 17:24:16 -07006824 if (IS_ERR_OR_NULL(bt_debugfs))
6825 return 0;
6826
6827 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6828 NULL, &l2cap_debugfs_fops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006829
Linus Torvalds1da177e2005-04-16 15:20:36 -07006830 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006831}
6832
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006833void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006834{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006835 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006836 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006837}
6838
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006839module_param(disable_ertm, bool, 0644);
6840MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");