blob: 1c94e51a28fed0b2f5cced0031c13ab613b960b0 [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
Johan Hedberg38319712013-05-17 12:49:23 +0300493void l2cap_le_flowctl_init(struct l2cap_chan *chan)
494{
495 chan->imtu = L2CAP_DEFAULT_MTU;
496 chan->omtu = L2CAP_LE_MIN_MTU;
497 chan->mode = L2CAP_MODE_LE_FLOWCTL;
Johan Hedberg0cd75f72013-05-17 13:09:05 +0300498 chan->tx_credits = 0;
499 chan->rx_credits = L2CAP_LE_MAX_CREDITS;
Johan Hedberg38319712013-05-17 12:49:23 +0300500}
501
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300502void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200503{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300504 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200505 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200506
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200507 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100508
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300509 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200510
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200511 switch (chan->chan_type) {
512 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300513 if (conn->hcon->type == LE_LINK) {
514 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300515 chan->omtu = L2CAP_DEFAULT_MTU;
Johan Hedberg9f22398c2013-04-29 19:35:38 +0300516 if (chan->dcid == L2CAP_CID_ATT)
517 chan->scid = L2CAP_CID_ATT;
518 else
519 chan->scid = l2cap_alloc_cid(conn);
Ville Tervob62f3282011-02-10 22:38:50 -0300520 } else {
521 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300522 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300523 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300524 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200525 break;
526
527 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200528 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300529 chan->scid = L2CAP_CID_CONN_LESS;
530 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300531 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200532 break;
533
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300534 case L2CAP_CHAN_CONN_FIX_A2MP:
535 chan->scid = L2CAP_CID_A2MP;
536 chan->dcid = L2CAP_CID_A2MP;
537 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
538 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
539 break;
540
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200541 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200542 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300543 chan->scid = L2CAP_CID_SIGNALING;
544 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300545 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200546 }
547
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300548 chan->local_id = L2CAP_BESTEFFORT_ID;
549 chan->local_stype = L2CAP_SERV_BESTEFFORT;
550 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
551 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
552 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300553 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300554
Ulisses Furquim371fd832011-12-21 20:02:36 -0200555 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300556
Johan Hedberg5ee98912013-04-29 19:35:43 +0300557 hci_conn_hold(conn->hcon);
558
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200559 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200560}
561
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300562void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200563{
564 mutex_lock(&conn->chan_lock);
565 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200566 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200567}
568
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300569void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200570{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300571 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200572
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300573 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200574
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300575 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200576
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900577 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300578 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300579 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200580 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200581
Ulisses Furquim371fd832011-12-21 20:02:36 -0200582 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300583
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300584 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300585
586 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
David Herrmann76a68ba2013-04-06 20:28:37 +0200587 hci_conn_drop(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300588
589 if (mgr && mgr->bredr_chan == chan)
590 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200591 }
592
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200593 if (chan->hs_hchan) {
594 struct hci_chan *hs_hchan = chan->hs_hchan;
595
596 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
597 amp_disconnect_logical_link(hs_hchan);
598 }
599
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100600 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200601
Mat Martineau28270112012-05-17 21:14:09 -0700602 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300603 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300604
Gustavo Padovanee556f62012-05-18 20:22:38 -0300605 switch(chan->mode) {
606 case L2CAP_MODE_BASIC:
607 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300608
Johan Hedberg38319712013-05-17 12:49:23 +0300609 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedberg177f8f22013-05-31 17:54:51 +0300610 skb_queue_purge(&chan->tx_q);
Johan Hedberg38319712013-05-17 12:49:23 +0300611 break;
612
Gustavo Padovanee556f62012-05-18 20:22:38 -0300613 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300614 __clear_retrans_timer(chan);
615 __clear_monitor_timer(chan);
616 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300617
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300618 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300619
Mat Martineau3c588192012-04-11 10:48:42 -0700620 l2cap_seq_list_free(&chan->srej_list);
621 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300622
623 /* fall through */
624
625 case L2CAP_MODE_STREAMING:
626 skb_queue_purge(&chan->tx_q);
627 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300628 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300629
630 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200631}
632
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300633static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan)
634{
635 struct l2cap_conn *conn = chan->conn;
636 struct l2cap_le_conn_rsp rsp;
637 u16 result;
638
639 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
640 result = L2CAP_CR_AUTHORIZATION;
641 else
642 result = L2CAP_CR_BAD_PSM;
643
644 l2cap_state_change(chan, BT_DISCONN);
645
646 rsp.dcid = cpu_to_le16(chan->scid);
647 rsp.mtu = cpu_to_le16(chan->imtu);
648 rsp.mps = __constant_cpu_to_le16(L2CAP_LE_DEFAULT_MPS);
Johan Hedberg0cd75f72013-05-17 13:09:05 +0300649 rsp.credits = cpu_to_le16(chan->rx_credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300650 rsp.result = cpu_to_le16(result);
651
652 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
653 &rsp);
654}
655
Johan Hedberg791d60f2013-05-14 22:24:44 +0300656static void l2cap_chan_connect_reject(struct l2cap_chan *chan)
657{
658 struct l2cap_conn *conn = chan->conn;
659 struct l2cap_conn_rsp rsp;
660 u16 result;
661
662 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
663 result = L2CAP_CR_SEC_BLOCK;
664 else
665 result = L2CAP_CR_BAD_PSM;
666
667 l2cap_state_change(chan, BT_DISCONN);
668
669 rsp.scid = cpu_to_le16(chan->dcid);
670 rsp.dcid = cpu_to_le16(chan->scid);
671 rsp.result = cpu_to_le16(result);
672 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
673
674 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
675}
676
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300677void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300678{
679 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300680
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700681 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300682
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300683 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300684 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100685 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300686 break;
687
688 case BT_CONNECTED:
689 case BT_CONFIG:
Johan Hedbergcea04ce32013-05-14 22:46:01 +0300690 /* ATT uses L2CAP_CHAN_CONN_ORIENTED so we must also
691 * check for chan->psm.
692 */
693 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && chan->psm) {
Gustavo Padovan8d836d72013-10-15 19:24:47 -0300694 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200695 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300696 } else
697 l2cap_chan_del(chan, reason);
698 break;
699
700 case BT_CONNECT2:
Johan Hedberg791d60f2013-05-14 22:24:44 +0300701 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED) {
702 if (conn->hcon->type == ACL_LINK)
703 l2cap_chan_connect_reject(chan);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300704 else if (conn->hcon->type == LE_LINK)
705 l2cap_chan_le_connect_reject(chan);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300706 }
707
708 l2cap_chan_del(chan, reason);
709 break;
710
711 case BT_CONNECT:
712 case BT_DISCONN:
713 l2cap_chan_del(chan, reason);
714 break;
715
716 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100717 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300718 break;
719 }
720}
721
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300722static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530723{
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700724 switch (chan->chan_type) {
725 case L2CAP_CHAN_RAW:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300726 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530727 case BT_SECURITY_HIGH:
728 return HCI_AT_DEDICATED_BONDING_MITM;
729 case BT_SECURITY_MEDIUM:
730 return HCI_AT_DEDICATED_BONDING;
731 default:
732 return HCI_AT_NO_BONDING;
733 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700734 break;
Marcel Holtmann3124b842013-10-12 07:19:32 -0700735 case L2CAP_CHAN_CONN_LESS:
736 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_3DSP)) {
737 if (chan->sec_level == BT_SECURITY_LOW)
738 chan->sec_level = BT_SECURITY_SDP;
739 }
740 if (chan->sec_level == BT_SECURITY_HIGH)
741 return HCI_AT_NO_BONDING_MITM;
742 else
743 return HCI_AT_NO_BONDING;
744 break;
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700745 case L2CAP_CHAN_CONN_ORIENTED:
746 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
747 if (chan->sec_level == BT_SECURITY_LOW)
748 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530749
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700750 if (chan->sec_level == BT_SECURITY_HIGH)
751 return HCI_AT_NO_BONDING_MITM;
752 else
753 return HCI_AT_NO_BONDING;
754 }
755 /* fall through */
756 default:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300757 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530758 case BT_SECURITY_HIGH:
759 return HCI_AT_GENERAL_BONDING_MITM;
760 case BT_SECURITY_MEDIUM:
761 return HCI_AT_GENERAL_BONDING;
762 default:
763 return HCI_AT_NO_BONDING;
764 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700765 break;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530766 }
767}
768
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200769/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200770int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200771{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300772 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100773 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200774
Johan Hedberga17de2f2013-05-14 13:25:37 +0300775 if (conn->hcon->type == LE_LINK)
776 return smp_conn_security(conn->hcon, chan->sec_level);
777
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300778 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100779
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300780 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200781}
782
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200783static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200784{
785 u8 id;
786
787 /* Get next available identificator.
788 * 1 - 128 are used by kernel.
789 * 129 - 199 are reserved.
790 * 200 - 254 are used by utilities like l2ping, etc.
791 */
792
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200793 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200794
795 if (++conn->tx_ident > 128)
796 conn->tx_ident = 1;
797
798 id = conn->tx_ident;
799
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200800 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200801
802 return id;
803}
804
Gustavo Padovan2d792812012-10-06 10:07:01 +0100805static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
806 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200807{
808 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200809 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200810
811 BT_DBG("code 0x%2.2x", code);
812
813 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300814 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200815
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200816 if (lmp_no_flush_capable(conn->hcon->hdev))
817 flags = ACL_START_NO_FLUSH;
818 else
819 flags = ACL_START;
820
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700821 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200822 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700823
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200824 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200825}
826
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700827static bool __chan_is_moving(struct l2cap_chan *chan)
828{
829 return chan->move_state != L2CAP_MOVE_STABLE &&
830 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
831}
832
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200833static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
834{
835 struct hci_conn *hcon = chan->conn->hcon;
836 u16 flags;
837
838 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100839 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200840
Mat Martineaud5f8a752012-10-23 15:24:18 -0700841 if (chan->hs_hcon && !__chan_is_moving(chan)) {
842 if (chan->hs_hchan)
843 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
844 else
845 kfree_skb(skb);
846
847 return;
848 }
849
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200850 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100851 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200852 flags = ACL_START_NO_FLUSH;
853 else
854 flags = ACL_START;
855
856 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
857 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858}
859
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700860static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
861{
862 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
863 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
864
865 if (enh & L2CAP_CTRL_FRAME_TYPE) {
866 /* S-Frame */
867 control->sframe = 1;
868 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
869 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
870
871 control->sar = 0;
872 control->txseq = 0;
873 } else {
874 /* I-Frame */
875 control->sframe = 0;
876 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
877 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
878
879 control->poll = 0;
880 control->super = 0;
881 }
882}
883
884static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
885{
886 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
887 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
888
889 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
890 /* S-Frame */
891 control->sframe = 1;
892 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
893 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
894
895 control->sar = 0;
896 control->txseq = 0;
897 } else {
898 /* I-Frame */
899 control->sframe = 0;
900 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
901 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
902
903 control->poll = 0;
904 control->super = 0;
905 }
906}
907
908static inline void __unpack_control(struct l2cap_chan *chan,
909 struct sk_buff *skb)
910{
911 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
912 __unpack_extended_control(get_unaligned_le32(skb->data),
913 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700914 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700915 } else {
916 __unpack_enhanced_control(get_unaligned_le16(skb->data),
917 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700918 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700919 }
920}
921
922static u32 __pack_extended_control(struct l2cap_ctrl *control)
923{
924 u32 packed;
925
926 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
927 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
928
929 if (control->sframe) {
930 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
931 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
932 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
933 } else {
934 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
935 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
936 }
937
938 return packed;
939}
940
941static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
942{
943 u16 packed;
944
945 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
946 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
947
948 if (control->sframe) {
949 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
950 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
951 packed |= L2CAP_CTRL_FRAME_TYPE;
952 } else {
953 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
954 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
955 }
956
957 return packed;
958}
959
960static inline void __pack_control(struct l2cap_chan *chan,
961 struct l2cap_ctrl *control,
962 struct sk_buff *skb)
963{
964 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
965 put_unaligned_le32(__pack_extended_control(control),
966 skb->data + L2CAP_HDR_SIZE);
967 } else {
968 put_unaligned_le16(__pack_enhanced_control(control),
969 skb->data + L2CAP_HDR_SIZE);
970 }
971}
972
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300973static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
974{
975 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
976 return L2CAP_EXT_HDR_SIZE;
977 else
978 return L2CAP_ENH_HDR_SIZE;
979}
980
Mat Martineaua67d7f62012-05-17 20:53:35 -0700981static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
982 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300983{
984 struct sk_buff *skb;
985 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300986 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300987
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300988 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300989 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300990
Mat Martineaua67d7f62012-05-17 20:53:35 -0700991 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300992
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300993 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700994 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300995
996 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300997 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300998 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300999
Mat Martineaua67d7f62012-05-17 20:53:35 -07001000 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1001 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
1002 else
1003 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001004
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001005 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -07001006 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03001007 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001008 }
1009
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001010 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -07001011 return skb;
1012}
1013
1014static void l2cap_send_sframe(struct l2cap_chan *chan,
1015 struct l2cap_ctrl *control)
1016{
1017 struct sk_buff *skb;
1018 u32 control_field;
1019
1020 BT_DBG("chan %p, control %p", chan, control);
1021
1022 if (!control->sframe)
1023 return;
1024
Mat Martineaub99e13a2012-10-23 15:24:19 -07001025 if (__chan_is_moving(chan))
1026 return;
1027
Mat Martineaua67d7f62012-05-17 20:53:35 -07001028 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
1029 !control->poll)
1030 control->final = 1;
1031
1032 if (control->super == L2CAP_SUPER_RR)
1033 clear_bit(CONN_RNR_SENT, &chan->conn_state);
1034 else if (control->super == L2CAP_SUPER_RNR)
1035 set_bit(CONN_RNR_SENT, &chan->conn_state);
1036
1037 if (control->super != L2CAP_SUPER_SREJ) {
1038 chan->last_acked_seq = control->reqseq;
1039 __clear_ack_timer(chan);
1040 }
1041
1042 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
1043 control->final, control->poll, control->super);
1044
1045 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1046 control_field = __pack_extended_control(control);
1047 else
1048 control_field = __pack_enhanced_control(control);
1049
1050 skb = l2cap_create_sframe_pdu(chan, control_field);
1051 if (!IS_ERR(skb))
1052 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001053}
1054
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001055static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001056{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001057 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001058
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001059 BT_DBG("chan %p, poll %d", chan, poll);
1060
1061 memset(&control, 0, sizeof(control));
1062 control.sframe = 1;
1063 control.poll = poll;
1064
1065 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
1066 control.super = L2CAP_SUPER_RNR;
1067 else
1068 control.super = L2CAP_SUPER_RR;
1069
1070 control.reqseq = chan->buffer_seq;
1071 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001072}
1073
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001074static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001075{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001076 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001077}
1078
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001079static bool __amp_capable(struct l2cap_chan *chan)
1080{
1081 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001082 struct hci_dev *hdev;
1083 bool amp_available = false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001084
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001085 if (!conn->hs_enabled)
1086 return false;
1087
1088 if (!(conn->fixed_chan_mask & L2CAP_FC_A2MP))
1089 return false;
1090
1091 read_lock(&hci_dev_list_lock);
1092 list_for_each_entry(hdev, &hci_dev_list, list) {
1093 if (hdev->amp_type != AMP_TYPE_BREDR &&
1094 test_bit(HCI_UP, &hdev->flags)) {
1095 amp_available = true;
1096 break;
1097 }
1098 }
1099 read_unlock(&hci_dev_list_lock);
1100
1101 if (chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED)
1102 return amp_available;
Marcel Holtmann848566b2013-10-01 22:59:22 -07001103
1104 return false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001105}
1106
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001107static bool l2cap_check_efs(struct l2cap_chan *chan)
1108{
1109 /* Check EFS parameters */
1110 return true;
1111}
1112
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001113void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001114{
1115 struct l2cap_conn *conn = chan->conn;
1116 struct l2cap_conn_req req;
1117
1118 req.scid = cpu_to_le16(chan->scid);
1119 req.psm = chan->psm;
1120
1121 chan->ident = l2cap_get_ident(conn);
1122
1123 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1124
1125 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1126}
1127
Mat Martineau8eb200b2012-10-23 15:24:17 -07001128static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1129{
1130 struct l2cap_create_chan_req req;
1131 req.scid = cpu_to_le16(chan->scid);
1132 req.psm = chan->psm;
1133 req.amp_id = amp_id;
1134
1135 chan->ident = l2cap_get_ident(chan->conn);
1136
1137 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1138 sizeof(req), &req);
1139}
1140
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001141static void l2cap_move_setup(struct l2cap_chan *chan)
1142{
1143 struct sk_buff *skb;
1144
1145 BT_DBG("chan %p", chan);
1146
1147 if (chan->mode != L2CAP_MODE_ERTM)
1148 return;
1149
1150 __clear_retrans_timer(chan);
1151 __clear_monitor_timer(chan);
1152 __clear_ack_timer(chan);
1153
1154 chan->retry_count = 0;
1155 skb_queue_walk(&chan->tx_q, skb) {
1156 if (bt_cb(skb)->control.retries)
1157 bt_cb(skb)->control.retries = 1;
1158 else
1159 break;
1160 }
1161
1162 chan->expected_tx_seq = chan->buffer_seq;
1163
1164 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1165 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1166 l2cap_seq_list_clear(&chan->retrans_list);
1167 l2cap_seq_list_clear(&chan->srej_list);
1168 skb_queue_purge(&chan->srej_q);
1169
1170 chan->tx_state = L2CAP_TX_STATE_XMIT;
1171 chan->rx_state = L2CAP_RX_STATE_MOVE;
1172
1173 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1174}
1175
Mat Martineau5f3847a2012-10-23 15:24:12 -07001176static void l2cap_move_done(struct l2cap_chan *chan)
1177{
1178 u8 move_role = chan->move_role;
1179 BT_DBG("chan %p", chan);
1180
1181 chan->move_state = L2CAP_MOVE_STABLE;
1182 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1183
1184 if (chan->mode != L2CAP_MODE_ERTM)
1185 return;
1186
1187 switch (move_role) {
1188 case L2CAP_MOVE_ROLE_INITIATOR:
1189 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1190 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1191 break;
1192 case L2CAP_MOVE_ROLE_RESPONDER:
1193 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1194 break;
1195 }
1196}
1197
Johan Hedberg177f8f22013-05-31 17:54:51 +03001198static void l2cap_le_flowctl_start(struct l2cap_chan *chan)
1199{
1200 chan->sdu = NULL;
1201 chan->sdu_last_frag = NULL;
1202 chan->sdu_len = 0;
1203
1204 skb_queue_head_init(&chan->tx_q);
1205}
1206
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001207static void l2cap_chan_ready(struct l2cap_chan *chan)
1208{
Mat Martineau28270112012-05-17 21:14:09 -07001209 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001210 chan->conf_state = 0;
1211 __clear_chan_timer(chan);
1212
Johan Hedberg177f8f22013-05-31 17:54:51 +03001213 if (chan->mode == L2CAP_MODE_LE_FLOWCTL)
1214 l2cap_le_flowctl_start(chan);
1215
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001216 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001217
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001218 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001219}
1220
Johan Hedbergf1496de2013-05-13 14:15:56 +03001221static void l2cap_le_connect(struct l2cap_chan *chan)
1222{
1223 struct l2cap_conn *conn = chan->conn;
1224 struct l2cap_le_conn_req req;
1225
1226 req.psm = chan->psm;
1227 req.scid = cpu_to_le16(chan->scid);
1228 req.mtu = cpu_to_le16(chan->imtu);
1229 req.mps = __constant_cpu_to_le16(L2CAP_LE_DEFAULT_MPS);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03001230 req.credits = cpu_to_le16(chan->rx_credits);
Johan Hedbergf1496de2013-05-13 14:15:56 +03001231
1232 chan->ident = l2cap_get_ident(conn);
1233
1234 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_REQ,
1235 sizeof(req), &req);
1236}
1237
1238static void l2cap_le_start(struct l2cap_chan *chan)
1239{
1240 struct l2cap_conn *conn = chan->conn;
1241
1242 if (!smp_conn_security(conn->hcon, chan->sec_level))
1243 return;
1244
1245 if (!chan->psm) {
1246 l2cap_chan_ready(chan);
1247 return;
1248 }
1249
1250 if (chan->state == BT_CONNECT)
1251 l2cap_le_connect(chan);
1252}
1253
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001254static void l2cap_start_connection(struct l2cap_chan *chan)
1255{
1256 if (__amp_capable(chan)) {
1257 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1258 a2mp_discover_amp(chan);
Johan Hedbergf1496de2013-05-13 14:15:56 +03001259 } else if (chan->conn->hcon->type == LE_LINK) {
1260 l2cap_le_start(chan);
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001261 } else {
1262 l2cap_send_conn_req(chan);
1263 }
1264}
1265
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001266static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001267{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001268 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001269
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001270 if (conn->hcon->type == LE_LINK) {
Johan Hedberg96ac34f2013-05-13 11:15:07 +03001271 l2cap_le_start(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001272 return;
1273 }
1274
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001275 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001276 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1277 return;
1278
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001279 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001280 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001281 l2cap_start_connection(chan);
1282 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001283 } else {
1284 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001285 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001286
1287 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1288 conn->info_ident = l2cap_get_ident(conn);
1289
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001290 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001291
Gustavo Padovan2d792812012-10-06 10:07:01 +01001292 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1293 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001294 }
1295}
1296
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001297static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1298{
1299 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001300 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001301 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1302
1303 switch (mode) {
1304 case L2CAP_MODE_ERTM:
1305 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1306 case L2CAP_MODE_STREAMING:
1307 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1308 default:
1309 return 0x00;
1310 }
1311}
1312
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001313static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001314{
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001315 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001316 struct l2cap_disconn_req req;
1317
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001318 if (!conn)
1319 return;
1320
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001321 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001322 __clear_retrans_timer(chan);
1323 __clear_monitor_timer(chan);
1324 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001325 }
1326
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001327 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001328 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001329 return;
1330 }
1331
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001332 req.dcid = cpu_to_le16(chan->dcid);
1333 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001334 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1335 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001336
Gustavo Padovanf8e73012013-10-15 19:24:46 -03001337 l2cap_state_change_and_error(chan, BT_DISCONN, err);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001338}
1339
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001341static void l2cap_conn_start(struct l2cap_conn *conn)
1342{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001343 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001344
1345 BT_DBG("conn %p", conn);
1346
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001347 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001348
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001349 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001350 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001351
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001352 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001353 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001354 continue;
1355 }
1356
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001357 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001358 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001359 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001360 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001361 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001362 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001363
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001364 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001365 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001366 &chan->conf_state)) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001367 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001368 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001369 continue;
1370 }
1371
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001372 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001373
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001374 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001375 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001376 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001377 rsp.scid = cpu_to_le16(chan->dcid);
1378 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001379
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001380 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07001381 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001382 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1383 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001384 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001385
1386 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02001387 l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001388 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1389 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001390 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001391 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001392 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1393 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001394 }
1395
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001396 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001397 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001398
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001399 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001400 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001401 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001402 continue;
1403 }
1404
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001405 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001406 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001407 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001408 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001409 }
1410
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001411 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001412 }
1413
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001414 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001415}
1416
Ido Yarivc2287682012-04-20 15:46:07 -03001417/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001418 * Returns closest match, locked.
1419 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001420static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001421 bdaddr_t *src,
1422 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001423{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001424 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001425
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001426 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001427
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001428 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001429 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001430 continue;
1431
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001432 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001433 int src_match, dst_match;
1434 int src_any, dst_any;
1435
Ville Tervob62f3282011-02-10 22:38:50 -03001436 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001437 src_match = !bacmp(&c->src, src);
1438 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001439 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001440 read_unlock(&chan_list_lock);
1441 return c;
1442 }
Ville Tervob62f3282011-02-10 22:38:50 -03001443
1444 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001445 src_any = !bacmp(&c->src, BDADDR_ANY);
1446 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001447 if ((src_match && dst_any) || (src_any && dst_match) ||
1448 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001449 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001450 }
1451 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001452
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001453 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001454
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001455 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001456}
1457
1458static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1459{
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001460 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001461 struct l2cap_chan *chan, *pchan;
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001462 u8 dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001463
1464 BT_DBG("");
1465
1466 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001467 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001468 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001469 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001470 return;
1471
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001472 /* Client ATT sockets should override the server one */
1473 if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
1474 return;
1475
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001476 dst_type = bdaddr_type(hcon, hcon->dst_type);
1477
1478 /* If device is blocked, do not create a channel for it */
1479 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, dst_type))
1480 return;
1481
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001482 l2cap_chan_lock(pchan);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001483
Gustavo Padovan80b98022012-05-27 22:27:51 -03001484 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001485 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001486 goto clean;
1487
Johan Hedberg9f22398c2013-04-29 19:35:38 +03001488 chan->dcid = L2CAP_CID_ATT;
1489
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001490 bacpy(&chan->src, &hcon->src);
1491 bacpy(&chan->dst, &hcon->dst);
1492 chan->src_type = bdaddr_type(hcon, hcon->src_type);
1493 chan->dst_type = dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001494
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001495 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001496
Ville Tervob62f3282011-02-10 22:38:50 -03001497clean:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001498 l2cap_chan_unlock(pchan);
Ville Tervob62f3282011-02-10 22:38:50 -03001499}
1500
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001501static void l2cap_conn_ready(struct l2cap_conn *conn)
1502{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001503 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001504 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001505
1506 BT_DBG("conn %p", conn);
1507
Johan Hedbergd8729922013-04-29 19:35:39 +03001508 /* For outgoing pairing which doesn't necessarily have an
1509 * associated socket (e.g. mgmt_pair_device).
1510 */
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001511 if (hcon->out && hcon->type == LE_LINK)
1512 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001513
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001514 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001515
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001516 if (hcon->type == LE_LINK)
1517 l2cap_le_conn_ready(conn);
1518
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001519 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001520
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001521 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001522
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001523 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1524 l2cap_chan_unlock(chan);
1525 continue;
1526 }
1527
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001528 if (hcon->type == LE_LINK) {
Johan Hedbergf1496de2013-05-13 14:15:56 +03001529 l2cap_le_start(chan);
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001530 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo Padovan74e75742013-10-15 19:24:51 -03001531 l2cap_chan_ready(chan);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001532
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001533 } else if (chan->state == BT_CONNECT) {
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001534 l2cap_do_start(chan);
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001535 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001536
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001537 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001538 }
1539
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001540 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001541}
1542
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001543/* Notify sockets that we cannot guaranty reliability anymore */
1544static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1545{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001546 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001547
1548 BT_DBG("conn %p", conn);
1549
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001550 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001551
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001552 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001553 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001554 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001555 }
1556
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001557 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001558}
1559
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001560static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001561{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001562 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001563 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001564
Marcel Holtmann984947d2009-02-06 23:35:19 +01001565 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001566 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001567
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001568 l2cap_conn_start(conn);
1569}
1570
David Herrmann2c8e1412013-04-06 20:28:45 +02001571/*
1572 * l2cap_user
1573 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1574 * callback is called during registration. The ->remove callback is called
1575 * during unregistration.
1576 * An l2cap_user object can either be explicitly unregistered or when the
1577 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1578 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1579 * External modules must own a reference to the l2cap_conn object if they intend
1580 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1581 * any time if they don't.
1582 */
1583
1584int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1585{
1586 struct hci_dev *hdev = conn->hcon->hdev;
1587 int ret;
1588
1589 /* We need to check whether l2cap_conn is registered. If it is not, we
1590 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1591 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1592 * relies on the parent hci_conn object to be locked. This itself relies
1593 * on the hci_dev object to be locked. So we must lock the hci device
1594 * here, too. */
1595
1596 hci_dev_lock(hdev);
1597
1598 if (user->list.next || user->list.prev) {
1599 ret = -EINVAL;
1600 goto out_unlock;
1601 }
1602
1603 /* conn->hchan is NULL after l2cap_conn_del() was called */
1604 if (!conn->hchan) {
1605 ret = -ENODEV;
1606 goto out_unlock;
1607 }
1608
1609 ret = user->probe(conn, user);
1610 if (ret)
1611 goto out_unlock;
1612
1613 list_add(&user->list, &conn->users);
1614 ret = 0;
1615
1616out_unlock:
1617 hci_dev_unlock(hdev);
1618 return ret;
1619}
1620EXPORT_SYMBOL(l2cap_register_user);
1621
1622void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1623{
1624 struct hci_dev *hdev = conn->hcon->hdev;
1625
1626 hci_dev_lock(hdev);
1627
1628 if (!user->list.next || !user->list.prev)
1629 goto out_unlock;
1630
1631 list_del(&user->list);
1632 user->list.next = NULL;
1633 user->list.prev = NULL;
1634 user->remove(conn, user);
1635
1636out_unlock:
1637 hci_dev_unlock(hdev);
1638}
1639EXPORT_SYMBOL(l2cap_unregister_user);
1640
1641static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1642{
1643 struct l2cap_user *user;
1644
1645 while (!list_empty(&conn->users)) {
1646 user = list_first_entry(&conn->users, struct l2cap_user, list);
1647 list_del(&user->list);
1648 user->list.next = NULL;
1649 user->list.prev = NULL;
1650 user->remove(conn, user);
1651 }
1652}
1653
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001654static void l2cap_conn_del(struct hci_conn *hcon, int err)
1655{
1656 struct l2cap_conn *conn = hcon->l2cap_data;
1657 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001658
1659 if (!conn)
1660 return;
1661
1662 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1663
1664 kfree_skb(conn->rx_skb);
1665
David Herrmann2c8e1412013-04-06 20:28:45 +02001666 l2cap_unregister_all_users(conn);
1667
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001668 mutex_lock(&conn->chan_lock);
1669
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001670 /* Kill channels */
1671 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001672 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001673 l2cap_chan_lock(chan);
1674
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001675 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001676
1677 l2cap_chan_unlock(chan);
1678
Gustavo Padovan80b98022012-05-27 22:27:51 -03001679 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001680 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001681 }
1682
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001683 mutex_unlock(&conn->chan_lock);
1684
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001685 hci_chan_del(conn->hchan);
1686
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001687 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001688 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001689
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001690 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001691 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001692 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001693 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001694
1695 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001696 conn->hchan = NULL;
1697 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001698}
1699
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001700static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001701{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001702 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001703 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001704
Johan Hedbergd06cc412012-06-06 18:44:11 +08001705 BT_DBG("conn %p", conn);
1706
1707 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1708 smp_chan_destroy(conn);
1709 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1710 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001711}
1712
Claudio Takahasibaf43252013-04-11 13:55:50 -03001713static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714{
Marcel Holtmann01394182006-07-03 10:02:46 +02001715 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001716 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717
Claudio Takahasibaf43252013-04-11 13:55:50 -03001718 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 return conn;
1720
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001721 hchan = hci_chan_create(hcon);
1722 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001725 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001726 if (!conn) {
1727 hci_chan_del(hchan);
1728 return NULL;
1729 }
1730
David Herrmann9c903e32013-04-06 20:28:44 +02001731 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732 hcon->l2cap_data = conn;
1733 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001734 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001735 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001737 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001738
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001739 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001740 case LE_LINK:
1741 if (hcon->hdev->le_mtu) {
1742 conn->mtu = hcon->hdev->le_mtu;
1743 break;
1744 }
1745 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001746 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001747 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001748 break;
1749 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001750
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001751 conn->feat_mask = 0;
1752
Marcel Holtmann848566b2013-10-01 22:59:22 -07001753 if (hcon->type == ACL_LINK)
1754 conn->hs_enabled = test_bit(HCI_HS_ENABLED,
1755 &hcon->hdev->dev_flags);
1756
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001758 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001759
1760 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001761 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001763 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001764 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001765 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001766 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001767
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001768 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001769
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770 return conn;
1771}
1772
David Herrmann9c903e32013-04-06 20:28:44 +02001773static void l2cap_conn_free(struct kref *ref)
1774{
1775 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1776
1777 hci_conn_put(conn->hcon);
1778 kfree(conn);
1779}
1780
1781void l2cap_conn_get(struct l2cap_conn *conn)
1782{
1783 kref_get(&conn->ref);
1784}
1785EXPORT_SYMBOL(l2cap_conn_get);
1786
1787void l2cap_conn_put(struct l2cap_conn *conn)
1788{
1789 kref_put(&conn->ref, l2cap_conn_free);
1790}
1791EXPORT_SYMBOL(l2cap_conn_put);
1792
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794
Ido Yarivc2287682012-04-20 15:46:07 -03001795/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796 * Returns closest match.
1797 */
Ido Yarivc2287682012-04-20 15:46:07 -03001798static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1799 bdaddr_t *src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001800 bdaddr_t *dst,
1801 u8 link_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001803 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001805 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001806
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001807 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001808 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 continue;
1810
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001811 if (link_type == ACL_LINK && c->src_type != BDADDR_BREDR)
1812 continue;
1813
1814 if (link_type == LE_LINK && c->src_type == BDADDR_BREDR)
1815 continue;
1816
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001817 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001818 int src_match, dst_match;
1819 int src_any, dst_any;
1820
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001822 src_match = !bacmp(&c->src, src);
1823 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001824 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001825 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001826 return c;
1827 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828
1829 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001830 src_any = !bacmp(&c->src, BDADDR_ANY);
1831 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001832 if ((src_match && dst_any) || (src_any && dst_match) ||
1833 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001834 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835 }
1836 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001838 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001839
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001840 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841}
1842
Andre Guedes8e9f9892012-04-24 21:02:55 -03001843int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1844 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846 struct l2cap_conn *conn;
1847 struct hci_conn *hcon;
1848 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001849 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001850 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001852 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301853 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001855 hdev = hci_get_route(dst, &chan->src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001856 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857 return -EHOSTUNREACH;
1858
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001859 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001861 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001862
1863 /* PSM must be odd and lsb of upper byte must be 0 */
1864 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001865 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001866 err = -EINVAL;
1867 goto done;
1868 }
1869
1870 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1871 err = -EINVAL;
1872 goto done;
1873 }
1874
1875 switch (chan->mode) {
1876 case L2CAP_MODE_BASIC:
Johan Hedberg38319712013-05-17 12:49:23 +03001877 case L2CAP_MODE_LE_FLOWCTL:
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001878 break;
1879 case L2CAP_MODE_ERTM:
1880 case L2CAP_MODE_STREAMING:
1881 if (!disable_ertm)
1882 break;
1883 /* fall through */
1884 default:
1885 err = -ENOTSUPP;
1886 goto done;
1887 }
1888
Gustavo Padovan0797e012012-05-27 22:27:54 -03001889 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001890 case BT_CONNECT:
1891 case BT_CONNECT2:
1892 case BT_CONFIG:
1893 /* Already connecting */
1894 err = 0;
1895 goto done;
1896
1897 case BT_CONNECTED:
1898 /* Already connected */
1899 err = -EISCONN;
1900 goto done;
1901
1902 case BT_OPEN:
1903 case BT_BOUND:
1904 /* Can connect */
1905 break;
1906
1907 default:
1908 err = -EBADFD;
1909 goto done;
1910 }
1911
1912 /* Set destination address and psm */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001913 bacpy(&chan->dst, dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001914 chan->dst_type = dst_type;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001915
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001916 chan->psm = psm;
1917 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001919 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001920
Johan Hedbergf224ca52013-04-29 19:35:36 +03001921 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001922 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001923 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001924 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001925 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001926 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001927
Ville Tervo30e76272011-02-22 16:10:53 -03001928 if (IS_ERR(hcon)) {
1929 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001930 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001931 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001932
Claudio Takahasibaf43252013-04-11 13:55:50 -03001933 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001935 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001936 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001937 goto done;
1938 }
1939
Johan Hedberg141d5702013-04-29 19:35:37 +03001940 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1941 hci_conn_drop(hcon);
1942 err = -EBUSY;
1943 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001944 }
1945
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946 /* Update source addr of the socket */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001947 bacpy(&chan->src, &hcon->src);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001948 chan->src_type = bdaddr_type(hcon, hcon->src_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001950 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001951 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001952 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001953
Johan Hedberg5ee98912013-04-29 19:35:43 +03001954 /* l2cap_chan_add takes its own ref so we can drop this one */
1955 hci_conn_drop(hcon);
1956
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001957 l2cap_state_change(chan, BT_CONNECT);
Gustavo Padovan8d836d72013-10-15 19:24:47 -03001958 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959
1960 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001961 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001962 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001963 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001964 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001965 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001966 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001967 }
1968
Ville Tervo30e76272011-02-22 16:10:53 -03001969 err = 0;
1970
Linus Torvalds1da177e2005-04-16 15:20:36 -07001971done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001972 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001973 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001974 hci_dev_put(hdev);
1975 return err;
1976}
1977
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001978static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001979{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001980 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001981 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001982
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001983 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001984
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001985 l2cap_chan_lock(chan);
1986
Mat Martineau80909e02012-05-17 20:53:50 -07001987 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001988 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001989 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001990 return;
1991 }
1992
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001993 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001994
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001995 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001996 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001997}
1998
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001999static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002000{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002001 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07002002 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002003
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03002004 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03002005
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002006 l2cap_chan_lock(chan);
2007
Mat Martineau80909e02012-05-17 20:53:50 -07002008 if (!chan->conn) {
2009 l2cap_chan_unlock(chan);
2010 l2cap_chan_put(chan);
2011 return;
2012 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002013
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002014 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002015 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02002016 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002017}
2018
Gustavo Padovand6603662012-05-21 13:58:22 -03002019static void l2cap_streaming_send(struct l2cap_chan *chan,
2020 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002021{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03002022 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07002023 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002024
Mat Martineau37339372012-05-17 20:53:33 -07002025 BT_DBG("chan %p, skbs %p", chan, skbs);
2026
Mat Martineaub99e13a2012-10-23 15:24:19 -07002027 if (__chan_is_moving(chan))
2028 return;
2029
Mat Martineau37339372012-05-17 20:53:33 -07002030 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2031
2032 while (!skb_queue_empty(&chan->tx_q)) {
2033
2034 skb = skb_dequeue(&chan->tx_q);
2035
2036 bt_cb(skb)->control.retries = 1;
2037 control = &bt_cb(skb)->control;
2038
2039 control->reqseq = 0;
2040 control->txseq = chan->next_tx_seq;
2041
2042 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002043
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002044 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07002045 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2046 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002047 }
2048
Gustavo F. Padovan43434782011-04-12 18:31:57 -03002049 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002050
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002051 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07002052
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002053 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07002054 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002055 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002056}
2057
Szymon Janc67c9e842011-07-28 16:24:33 +02002058static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002059{
2060 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07002061 struct l2cap_ctrl *control;
2062 int sent = 0;
2063
2064 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002065
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03002066 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03002067 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002068
Mat Martineau94122bb2012-05-02 09:42:02 -07002069 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2070 return 0;
2071
Mat Martineaub99e13a2012-10-23 15:24:19 -07002072 if (__chan_is_moving(chan))
2073 return 0;
2074
Mat Martineau18a48e72012-05-17 20:53:34 -07002075 while (chan->tx_send_head &&
2076 chan->unacked_frames < chan->remote_tx_win &&
2077 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002078
Mat Martineau18a48e72012-05-17 20:53:34 -07002079 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002080
Mat Martineau18a48e72012-05-17 20:53:34 -07002081 bt_cb(skb)->control.retries = 1;
2082 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03002083
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002084 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07002085 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002086
Mat Martineau18a48e72012-05-17 20:53:34 -07002087 control->reqseq = chan->buffer_seq;
2088 chan->last_acked_seq = chan->buffer_seq;
2089 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002090
Mat Martineau18a48e72012-05-17 20:53:34 -07002091 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002092
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002093 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07002094 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2095 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002096 }
2097
Mat Martineau18a48e72012-05-17 20:53:34 -07002098 /* Clone after data has been modified. Data is assumed to be
2099 read-only (for locking purposes) on cloned sk_buffs.
2100 */
2101 tx_skb = skb_clone(skb, GFP_KERNEL);
2102
2103 if (!tx_skb)
2104 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002105
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002106 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002107
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002108 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002109 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002110 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002111 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002112
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002113 if (skb_queue_is_last(&chan->tx_q, skb))
2114 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002115 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002116 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002117
2118 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002119 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002120 }
2121
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002122 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2123 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002124
2125 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002126}
2127
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002128static void l2cap_ertm_resend(struct l2cap_chan *chan)
2129{
2130 struct l2cap_ctrl control;
2131 struct sk_buff *skb;
2132 struct sk_buff *tx_skb;
2133 u16 seq;
2134
2135 BT_DBG("chan %p", chan);
2136
2137 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2138 return;
2139
Mat Martineaub99e13a2012-10-23 15:24:19 -07002140 if (__chan_is_moving(chan))
2141 return;
2142
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002143 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2144 seq = l2cap_seq_list_pop(&chan->retrans_list);
2145
2146 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2147 if (!skb) {
2148 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002149 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002150 continue;
2151 }
2152
2153 bt_cb(skb)->control.retries++;
2154 control = bt_cb(skb)->control;
2155
2156 if (chan->max_tx != 0 &&
2157 bt_cb(skb)->control.retries > chan->max_tx) {
2158 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002159 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002160 l2cap_seq_list_clear(&chan->retrans_list);
2161 break;
2162 }
2163
2164 control.reqseq = chan->buffer_seq;
2165 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2166 control.final = 1;
2167 else
2168 control.final = 0;
2169
2170 if (skb_cloned(skb)) {
2171 /* Cloned sk_buffs are read-only, so we need a
2172 * writeable copy
2173 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002174 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002175 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002176 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002177 }
2178
2179 if (!tx_skb) {
2180 l2cap_seq_list_clear(&chan->retrans_list);
2181 break;
2182 }
2183
2184 /* Update skb contents */
2185 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2186 put_unaligned_le32(__pack_extended_control(&control),
2187 tx_skb->data + L2CAP_HDR_SIZE);
2188 } else {
2189 put_unaligned_le16(__pack_enhanced_control(&control),
2190 tx_skb->data + L2CAP_HDR_SIZE);
2191 }
2192
2193 if (chan->fcs == L2CAP_FCS_CRC16) {
2194 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2195 put_unaligned_le16(fcs, skb_put(tx_skb,
2196 L2CAP_FCS_SIZE));
2197 }
2198
2199 l2cap_do_send(chan, tx_skb);
2200
2201 BT_DBG("Resent txseq %d", control.txseq);
2202
2203 chan->last_acked_seq = chan->buffer_seq;
2204 }
2205}
2206
Mat Martineauf80842a2012-05-17 20:53:46 -07002207static void l2cap_retransmit(struct l2cap_chan *chan,
2208 struct l2cap_ctrl *control)
2209{
2210 BT_DBG("chan %p, control %p", chan, control);
2211
2212 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2213 l2cap_ertm_resend(chan);
2214}
2215
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002216static void l2cap_retransmit_all(struct l2cap_chan *chan,
2217 struct l2cap_ctrl *control)
2218{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002219 struct sk_buff *skb;
2220
2221 BT_DBG("chan %p, control %p", chan, control);
2222
2223 if (control->poll)
2224 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2225
2226 l2cap_seq_list_clear(&chan->retrans_list);
2227
2228 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2229 return;
2230
2231 if (chan->unacked_frames) {
2232 skb_queue_walk(&chan->tx_q, skb) {
2233 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002234 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002235 break;
2236 }
2237
2238 skb_queue_walk_from(&chan->tx_q, skb) {
2239 if (skb == chan->tx_send_head)
2240 break;
2241
2242 l2cap_seq_list_append(&chan->retrans_list,
2243 bt_cb(skb)->control.txseq);
2244 }
2245
2246 l2cap_ertm_resend(chan);
2247 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002248}
2249
Szymon Jancb17e73b2012-01-11 10:59:47 +01002250static void l2cap_send_ack(struct l2cap_chan *chan)
2251{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002252 struct l2cap_ctrl control;
2253 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2254 chan->last_acked_seq);
2255 int threshold;
2256
2257 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2258 chan, chan->last_acked_seq, chan->buffer_seq);
2259
2260 memset(&control, 0, sizeof(control));
2261 control.sframe = 1;
2262
2263 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2264 chan->rx_state == L2CAP_RX_STATE_RECV) {
2265 __clear_ack_timer(chan);
2266 control.super = L2CAP_SUPER_RNR;
2267 control.reqseq = chan->buffer_seq;
2268 l2cap_send_sframe(chan, &control);
2269 } else {
2270 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2271 l2cap_ertm_send(chan);
2272 /* If any i-frames were sent, they included an ack */
2273 if (chan->buffer_seq == chan->last_acked_seq)
2274 frames_to_ack = 0;
2275 }
2276
Mat Martineauc20f8e32012-07-10 05:47:07 -07002277 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002278 * Calculate without mul or div
2279 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002280 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002281 threshold += threshold << 1;
2282 threshold >>= 2;
2283
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002284 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002285 threshold);
2286
2287 if (frames_to_ack >= threshold) {
2288 __clear_ack_timer(chan);
2289 control.super = L2CAP_SUPER_RR;
2290 control.reqseq = chan->buffer_seq;
2291 l2cap_send_sframe(chan, &control);
2292 frames_to_ack = 0;
2293 }
2294
2295 if (frames_to_ack)
2296 __set_ack_timer(chan);
2297 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002298}
2299
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002300static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2301 struct msghdr *msg, int len,
2302 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002303{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002304 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002305 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002306 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002307
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002308 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002309 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002310
2311 sent += count;
2312 len -= count;
2313
2314 /* Continuation fragments (no L2CAP header) */
2315 frag = &skb_shinfo(skb)->frag_list;
2316 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002317 struct sk_buff *tmp;
2318
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319 count = min_t(unsigned int, conn->mtu, len);
2320
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002321 tmp = chan->ops->alloc_skb(chan, count,
2322 msg->msg_flags & MSG_DONTWAIT);
2323 if (IS_ERR(tmp))
2324 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002325
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002326 *frag = tmp;
2327
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002328 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2329 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002330
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002331 (*frag)->priority = skb->priority;
2332
Linus Torvalds1da177e2005-04-16 15:20:36 -07002333 sent += count;
2334 len -= count;
2335
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002336 skb->len += (*frag)->len;
2337 skb->data_len += (*frag)->len;
2338
Linus Torvalds1da177e2005-04-16 15:20:36 -07002339 frag = &(*frag)->next;
2340 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002341
2342 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002343}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002344
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002345static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002346 struct msghdr *msg, size_t len,
2347 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002348{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002349 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002350 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002351 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002352 struct l2cap_hdr *lh;
2353
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002354 BT_DBG("chan %p psm 0x%2.2x len %zu priority %u", chan,
2355 __le16_to_cpu(chan->psm), len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002356
2357 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002358
2359 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002360 msg->msg_flags & MSG_DONTWAIT);
2361 if (IS_ERR(skb))
2362 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002363
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002364 skb->priority = priority;
2365
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002366 /* Create L2CAP header */
2367 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002368 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002369 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002370 put_unaligned(chan->psm, (__le16 *) skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002371
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002372 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002373 if (unlikely(err < 0)) {
2374 kfree_skb(skb);
2375 return ERR_PTR(err);
2376 }
2377 return skb;
2378}
2379
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002380static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002381 struct msghdr *msg, size_t len,
2382 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002383{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002384 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002385 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002386 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002387 struct l2cap_hdr *lh;
2388
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002389 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002390
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002391 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002392
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002393 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002394 msg->msg_flags & MSG_DONTWAIT);
2395 if (IS_ERR(skb))
2396 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002397
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002398 skb->priority = priority;
2399
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002400 /* Create L2CAP header */
2401 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002402 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002403 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002404
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002405 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002406 if (unlikely(err < 0)) {
2407 kfree_skb(skb);
2408 return ERR_PTR(err);
2409 }
2410 return skb;
2411}
2412
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002413static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002414 struct msghdr *msg, size_t len,
2415 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002416{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002417 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002418 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002419 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002420 struct l2cap_hdr *lh;
2421
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002422 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002423
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002424 if (!conn)
2425 return ERR_PTR(-ENOTCONN);
2426
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002427 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002428
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002429 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002430 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002431
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002432 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002433 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002434
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002435 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002436
2437 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002438 msg->msg_flags & MSG_DONTWAIT);
2439 if (IS_ERR(skb))
2440 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002441
2442 /* Create L2CAP header */
2443 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002444 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002445 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002446
Mat Martineau18a48e72012-05-17 20:53:34 -07002447 /* Control header is populated later */
2448 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2449 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2450 else
2451 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002452
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002453 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002454 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002455
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002456 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002457 if (unlikely(err < 0)) {
2458 kfree_skb(skb);
2459 return ERR_PTR(err);
2460 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002461
Mat Martineau18a48e72012-05-17 20:53:34 -07002462 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002463 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002464 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002465}
2466
Mat Martineau94122bb2012-05-02 09:42:02 -07002467static int l2cap_segment_sdu(struct l2cap_chan *chan,
2468 struct sk_buff_head *seg_queue,
2469 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002470{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002471 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002472 u16 sdu_len;
2473 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002474 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002475
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002476 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002477
Mat Martineau94122bb2012-05-02 09:42:02 -07002478 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2479 * so fragmented skbs are not used. The HCI layer's handling
2480 * of fragmented skbs is not compatible with ERTM's queueing.
2481 */
2482
2483 /* PDU size is derived from the HCI MTU */
2484 pdu_len = chan->conn->mtu;
2485
Mat Martineaua5495742012-10-23 15:24:21 -07002486 /* Constrain PDU size for BR/EDR connections */
2487 if (!chan->hs_hcon)
2488 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002489
2490 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002491 if (chan->fcs)
2492 pdu_len -= L2CAP_FCS_SIZE;
2493
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002494 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002495
2496 /* Remote device may have requested smaller PDUs */
2497 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2498
2499 if (len <= pdu_len) {
2500 sar = L2CAP_SAR_UNSEGMENTED;
2501 sdu_len = 0;
2502 pdu_len = len;
2503 } else {
2504 sar = L2CAP_SAR_START;
2505 sdu_len = len;
2506 pdu_len -= L2CAP_SDULEN_SIZE;
2507 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002508
2509 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002510 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002511
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002512 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002513 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002514 return PTR_ERR(skb);
2515 }
2516
Mat Martineau94122bb2012-05-02 09:42:02 -07002517 bt_cb(skb)->control.sar = sar;
2518 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002519
Mat Martineau94122bb2012-05-02 09:42:02 -07002520 len -= pdu_len;
2521 if (sdu_len) {
2522 sdu_len = 0;
2523 pdu_len += L2CAP_SDULEN_SIZE;
2524 }
2525
2526 if (len <= pdu_len) {
2527 sar = L2CAP_SAR_END;
2528 pdu_len = len;
2529 } else {
2530 sar = L2CAP_SAR_CONTINUE;
2531 }
2532 }
2533
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002534 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002535}
2536
Johan Hedberg177f8f22013-05-31 17:54:51 +03002537static struct sk_buff *l2cap_create_le_flowctl_pdu(struct l2cap_chan *chan,
2538 struct msghdr *msg,
2539 size_t len, u16 sdulen)
2540{
2541 struct l2cap_conn *conn = chan->conn;
2542 struct sk_buff *skb;
2543 int err, count, hlen;
2544 struct l2cap_hdr *lh;
2545
2546 BT_DBG("chan %p len %zu", chan, len);
2547
2548 if (!conn)
2549 return ERR_PTR(-ENOTCONN);
2550
2551 hlen = L2CAP_HDR_SIZE;
2552
2553 if (sdulen)
2554 hlen += L2CAP_SDULEN_SIZE;
2555
2556 count = min_t(unsigned int, (conn->mtu - hlen), len);
2557
2558 skb = chan->ops->alloc_skb(chan, count + hlen,
2559 msg->msg_flags & MSG_DONTWAIT);
2560 if (IS_ERR(skb))
2561 return skb;
2562
2563 /* Create L2CAP header */
2564 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
2565 lh->cid = cpu_to_le16(chan->dcid);
2566 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
2567
2568 if (sdulen)
2569 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
2570
2571 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
2572 if (unlikely(err < 0)) {
2573 kfree_skb(skb);
2574 return ERR_PTR(err);
2575 }
2576
2577 return skb;
2578}
2579
2580static int l2cap_segment_le_sdu(struct l2cap_chan *chan,
2581 struct sk_buff_head *seg_queue,
2582 struct msghdr *msg, size_t len)
2583{
2584 struct sk_buff *skb;
2585 size_t pdu_len;
2586 u16 sdu_len;
2587
2588 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
2589
2590 pdu_len = chan->conn->mtu - L2CAP_HDR_SIZE;
2591
2592 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2593
2594 sdu_len = len;
2595 pdu_len -= L2CAP_SDULEN_SIZE;
2596
2597 while (len > 0) {
2598 if (len <= pdu_len)
2599 pdu_len = len;
2600
2601 skb = l2cap_create_le_flowctl_pdu(chan, msg, pdu_len, sdu_len);
2602 if (IS_ERR(skb)) {
2603 __skb_queue_purge(seg_queue);
2604 return PTR_ERR(skb);
2605 }
2606
2607 __skb_queue_tail(seg_queue, skb);
2608
2609 len -= pdu_len;
2610
2611 if (sdu_len) {
2612 sdu_len = 0;
2613 pdu_len += L2CAP_SDULEN_SIZE;
2614 }
2615 }
2616
2617 return 0;
2618}
2619
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002620int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002621 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002622{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002623 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002624 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002625 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002626
Seung-Woo Kim31e8ce82013-11-05 18:46:33 +09002627 if (!chan->conn)
2628 return -ENOTCONN;
2629
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002630 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002631 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002632 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002633 if (IS_ERR(skb))
2634 return PTR_ERR(skb);
2635
2636 l2cap_do_send(chan, skb);
2637 return len;
2638 }
2639
2640 switch (chan->mode) {
Johan Hedberg38319712013-05-17 12:49:23 +03002641 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedberg177f8f22013-05-31 17:54:51 +03002642 /* Check outgoing MTU */
2643 if (len > chan->omtu)
2644 return -EMSGSIZE;
2645
Johan Hedbergfad5fc82013-12-05 09:45:01 +02002646 if (!chan->tx_credits)
2647 return -EAGAIN;
2648
Johan Hedberg177f8f22013-05-31 17:54:51 +03002649 __skb_queue_head_init(&seg_queue);
2650
2651 err = l2cap_segment_le_sdu(chan, &seg_queue, msg, len);
2652
2653 if (chan->state != BT_CONNECTED) {
2654 __skb_queue_purge(&seg_queue);
2655 err = -ENOTCONN;
2656 }
2657
2658 if (err)
2659 return err;
2660
2661 skb_queue_splice_tail_init(&seg_queue, &chan->tx_q);
2662
2663 while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
2664 l2cap_do_send(chan, skb_dequeue(&chan->tx_q));
2665 chan->tx_credits--;
2666 }
2667
2668 if (!chan->tx_credits)
2669 chan->ops->suspend(chan);
2670
2671 err = len;
2672
2673 break;
2674
Johan Hedbergfad5fc82013-12-05 09:45:01 +02002675 case L2CAP_MODE_BASIC:
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002676 /* Check outgoing MTU */
2677 if (len > chan->omtu)
2678 return -EMSGSIZE;
2679
2680 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002681 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002682 if (IS_ERR(skb))
2683 return PTR_ERR(skb);
2684
2685 l2cap_do_send(chan, skb);
2686 err = len;
2687 break;
2688
2689 case L2CAP_MODE_ERTM:
2690 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002691 /* Check outgoing MTU */
2692 if (len > chan->omtu) {
2693 err = -EMSGSIZE;
2694 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002695 }
2696
Mat Martineau94122bb2012-05-02 09:42:02 -07002697 __skb_queue_head_init(&seg_queue);
2698
2699 /* Do segmentation before calling in to the state machine,
2700 * since it's possible to block while waiting for memory
2701 * allocation.
2702 */
2703 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2704
2705 /* The channel could have been closed while segmenting,
2706 * check that it is still connected.
2707 */
2708 if (chan->state != BT_CONNECTED) {
2709 __skb_queue_purge(&seg_queue);
2710 err = -ENOTCONN;
2711 }
2712
2713 if (err)
2714 break;
2715
Mat Martineau37339372012-05-17 20:53:33 -07002716 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002717 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002718 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002719 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002720
Gustavo Padovand6603662012-05-21 13:58:22 -03002721 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002722
Mat Martineau94122bb2012-05-02 09:42:02 -07002723 /* If the skbs were not queued for sending, they'll still be in
2724 * seg_queue and need to be purged.
2725 */
2726 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002727 break;
2728
2729 default:
2730 BT_DBG("bad state %1.1x", chan->mode);
2731 err = -EBADFD;
2732 }
2733
2734 return err;
2735}
2736
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002737static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2738{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002739 struct l2cap_ctrl control;
2740 u16 seq;
2741
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002742 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002743
2744 memset(&control, 0, sizeof(control));
2745 control.sframe = 1;
2746 control.super = L2CAP_SUPER_SREJ;
2747
2748 for (seq = chan->expected_tx_seq; seq != txseq;
2749 seq = __next_seq(chan, seq)) {
2750 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2751 control.reqseq = seq;
2752 l2cap_send_sframe(chan, &control);
2753 l2cap_seq_list_append(&chan->srej_list, seq);
2754 }
2755 }
2756
2757 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002758}
2759
2760static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2761{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002762 struct l2cap_ctrl control;
2763
2764 BT_DBG("chan %p", chan);
2765
2766 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2767 return;
2768
2769 memset(&control, 0, sizeof(control));
2770 control.sframe = 1;
2771 control.super = L2CAP_SUPER_SREJ;
2772 control.reqseq = chan->srej_list.tail;
2773 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002774}
2775
2776static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2777{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002778 struct l2cap_ctrl control;
2779 u16 initial_head;
2780 u16 seq;
2781
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002782 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002783
2784 memset(&control, 0, sizeof(control));
2785 control.sframe = 1;
2786 control.super = L2CAP_SUPER_SREJ;
2787
2788 /* Capture initial list head to allow only one pass through the list. */
2789 initial_head = chan->srej_list.head;
2790
2791 do {
2792 seq = l2cap_seq_list_pop(&chan->srej_list);
2793 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2794 break;
2795
2796 control.reqseq = seq;
2797 l2cap_send_sframe(chan, &control);
2798 l2cap_seq_list_append(&chan->srej_list, seq);
2799 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002800}
2801
Mat Martineau608bcc62012-05-17 20:53:32 -07002802static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2803{
2804 struct sk_buff *acked_skb;
2805 u16 ackseq;
2806
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002807 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002808
2809 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2810 return;
2811
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002812 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002813 chan->expected_ack_seq, chan->unacked_frames);
2814
2815 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2816 ackseq = __next_seq(chan, ackseq)) {
2817
2818 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2819 if (acked_skb) {
2820 skb_unlink(acked_skb, &chan->tx_q);
2821 kfree_skb(acked_skb);
2822 chan->unacked_frames--;
2823 }
2824 }
2825
2826 chan->expected_ack_seq = reqseq;
2827
2828 if (chan->unacked_frames == 0)
2829 __clear_retrans_timer(chan);
2830
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002831 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002832}
2833
2834static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2835{
2836 BT_DBG("chan %p", chan);
2837
2838 chan->expected_tx_seq = chan->buffer_seq;
2839 l2cap_seq_list_clear(&chan->srej_list);
2840 skb_queue_purge(&chan->srej_q);
2841 chan->rx_state = L2CAP_RX_STATE_RECV;
2842}
2843
Gustavo Padovand6603662012-05-21 13:58:22 -03002844static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2845 struct l2cap_ctrl *control,
2846 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002847{
Mat Martineau608bcc62012-05-17 20:53:32 -07002848 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2849 event);
2850
2851 switch (event) {
2852 case L2CAP_EV_DATA_REQUEST:
2853 if (chan->tx_send_head == NULL)
2854 chan->tx_send_head = skb_peek(skbs);
2855
2856 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2857 l2cap_ertm_send(chan);
2858 break;
2859 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2860 BT_DBG("Enter LOCAL_BUSY");
2861 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2862
2863 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2864 /* The SREJ_SENT state must be aborted if we are to
2865 * enter the LOCAL_BUSY state.
2866 */
2867 l2cap_abort_rx_srej_sent(chan);
2868 }
2869
2870 l2cap_send_ack(chan);
2871
2872 break;
2873 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2874 BT_DBG("Exit LOCAL_BUSY");
2875 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2876
2877 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2878 struct l2cap_ctrl local_control;
2879
2880 memset(&local_control, 0, sizeof(local_control));
2881 local_control.sframe = 1;
2882 local_control.super = L2CAP_SUPER_RR;
2883 local_control.poll = 1;
2884 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002885 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002886
2887 chan->retry_count = 1;
2888 __set_monitor_timer(chan);
2889 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2890 }
2891 break;
2892 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2893 l2cap_process_reqseq(chan, control->reqseq);
2894 break;
2895 case L2CAP_EV_EXPLICIT_POLL:
2896 l2cap_send_rr_or_rnr(chan, 1);
2897 chan->retry_count = 1;
2898 __set_monitor_timer(chan);
2899 __clear_ack_timer(chan);
2900 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2901 break;
2902 case L2CAP_EV_RETRANS_TO:
2903 l2cap_send_rr_or_rnr(chan, 1);
2904 chan->retry_count = 1;
2905 __set_monitor_timer(chan);
2906 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2907 break;
2908 case L2CAP_EV_RECV_FBIT:
2909 /* Nothing to process */
2910 break;
2911 default:
2912 break;
2913 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002914}
2915
Gustavo Padovand6603662012-05-21 13:58:22 -03002916static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2917 struct l2cap_ctrl *control,
2918 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002919{
Mat Martineau608bcc62012-05-17 20:53:32 -07002920 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2921 event);
2922
2923 switch (event) {
2924 case L2CAP_EV_DATA_REQUEST:
2925 if (chan->tx_send_head == NULL)
2926 chan->tx_send_head = skb_peek(skbs);
2927 /* Queue data, but don't send. */
2928 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2929 break;
2930 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2931 BT_DBG("Enter LOCAL_BUSY");
2932 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2933
2934 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2935 /* The SREJ_SENT state must be aborted if we are to
2936 * enter the LOCAL_BUSY state.
2937 */
2938 l2cap_abort_rx_srej_sent(chan);
2939 }
2940
2941 l2cap_send_ack(chan);
2942
2943 break;
2944 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2945 BT_DBG("Exit LOCAL_BUSY");
2946 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2947
2948 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2949 struct l2cap_ctrl local_control;
2950 memset(&local_control, 0, sizeof(local_control));
2951 local_control.sframe = 1;
2952 local_control.super = L2CAP_SUPER_RR;
2953 local_control.poll = 1;
2954 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002955 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002956
2957 chan->retry_count = 1;
2958 __set_monitor_timer(chan);
2959 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2960 }
2961 break;
2962 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2963 l2cap_process_reqseq(chan, control->reqseq);
2964
2965 /* Fall through */
2966
2967 case L2CAP_EV_RECV_FBIT:
2968 if (control && control->final) {
2969 __clear_monitor_timer(chan);
2970 if (chan->unacked_frames > 0)
2971 __set_retrans_timer(chan);
2972 chan->retry_count = 0;
2973 chan->tx_state = L2CAP_TX_STATE_XMIT;
2974 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2975 }
2976 break;
2977 case L2CAP_EV_EXPLICIT_POLL:
2978 /* Ignore */
2979 break;
2980 case L2CAP_EV_MONITOR_TO:
2981 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2982 l2cap_send_rr_or_rnr(chan, 1);
2983 __set_monitor_timer(chan);
2984 chan->retry_count++;
2985 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002986 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002987 }
2988 break;
2989 default:
2990 break;
2991 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002992}
2993
Gustavo Padovand6603662012-05-21 13:58:22 -03002994static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2995 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002996{
Mat Martineau608bcc62012-05-17 20:53:32 -07002997 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2998 chan, control, skbs, event, chan->tx_state);
2999
3000 switch (chan->tx_state) {
3001 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03003002 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07003003 break;
3004 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03003005 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07003006 break;
3007 default:
3008 /* Ignore event */
3009 break;
3010 }
Mat Martineau608bcc62012-05-17 20:53:32 -07003011}
3012
Mat Martineau4b51dae92012-05-17 20:53:37 -07003013static void l2cap_pass_to_tx(struct l2cap_chan *chan,
3014 struct l2cap_ctrl *control)
3015{
3016 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03003017 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07003018}
3019
Mat Martineauf80842a2012-05-17 20:53:46 -07003020static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
3021 struct l2cap_ctrl *control)
3022{
3023 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03003024 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07003025}
3026
Linus Torvalds1da177e2005-04-16 15:20:36 -07003027/* Copy frame to all raw sockets on that connection */
3028static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
3029{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003030 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003031 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003032
3033 BT_DBG("conn %p", conn);
3034
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003035 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02003036
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003037 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03003038 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003039 continue;
3040
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02003041 /* Don't send frame to the channel it came from */
3042 if (bt_cb(skb)->chan == chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003043 continue;
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02003044
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03003045 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003046 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003047 continue;
Gustavo Padovan80b98022012-05-27 22:27:51 -03003048 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003049 kfree_skb(nskb);
3050 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02003051
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003052 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003053}
3054
3055/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003056static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
3057 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003058{
3059 struct sk_buff *skb, **frag;
3060 struct l2cap_cmd_hdr *cmd;
3061 struct l2cap_hdr *lh;
3062 int len, count;
3063
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003064 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
3065 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003066
Anderson Lizardo300b9622013-06-02 16:30:40 -04003067 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
3068 return NULL;
3069
Linus Torvalds1da177e2005-04-16 15:20:36 -07003070 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
3071 count = min_t(unsigned int, conn->mtu, len);
3072
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03003073 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003074 if (!skb)
3075 return NULL;
3076
3077 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003078 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02003079
3080 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003081 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02003082 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003083 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003084
3085 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
3086 cmd->code = code;
3087 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003088 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003089
3090 if (dlen) {
3091 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
3092 memcpy(skb_put(skb, count), data, count);
3093 data += count;
3094 }
3095
3096 len -= skb->len;
3097
3098 /* Continuation fragments (no L2CAP header) */
3099 frag = &skb_shinfo(skb)->frag_list;
3100 while (len) {
3101 count = min_t(unsigned int, conn->mtu, len);
3102
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03003103 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003104 if (!*frag)
3105 goto fail;
3106
3107 memcpy(skb_put(*frag, count), data, count);
3108
3109 len -= count;
3110 data += count;
3111
3112 frag = &(*frag)->next;
3113 }
3114
3115 return skb;
3116
3117fail:
3118 kfree_skb(skb);
3119 return NULL;
3120}
3121
Gustavo Padovan2d792812012-10-06 10:07:01 +01003122static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
3123 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003124{
3125 struct l2cap_conf_opt *opt = *ptr;
3126 int len;
3127
3128 len = L2CAP_CONF_OPT_SIZE + opt->len;
3129 *ptr += len;
3130
3131 *type = opt->type;
3132 *olen = opt->len;
3133
3134 switch (opt->len) {
3135 case 1:
3136 *val = *((u8 *) opt->val);
3137 break;
3138
3139 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04003140 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003141 break;
3142
3143 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04003144 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003145 break;
3146
3147 default:
3148 *val = (unsigned long) opt->val;
3149 break;
3150 }
3151
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003152 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003153 return len;
3154}
3155
Linus Torvalds1da177e2005-04-16 15:20:36 -07003156static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
3157{
3158 struct l2cap_conf_opt *opt = *ptr;
3159
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003160 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003161
3162 opt->type = type;
3163 opt->len = len;
3164
3165 switch (len) {
3166 case 1:
3167 *((u8 *) opt->val) = val;
3168 break;
3169
3170 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003171 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003172 break;
3173
3174 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003175 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003176 break;
3177
3178 default:
3179 memcpy(opt->val, (void *) val, len);
3180 break;
3181 }
3182
3183 *ptr += L2CAP_CONF_OPT_SIZE + len;
3184}
3185
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003186static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
3187{
3188 struct l2cap_conf_efs efs;
3189
Szymon Janc1ec918c2011-11-16 09:32:21 +01003190 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003191 case L2CAP_MODE_ERTM:
3192 efs.id = chan->local_id;
3193 efs.stype = chan->local_stype;
3194 efs.msdu = cpu_to_le16(chan->local_msdu);
3195 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003196 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003197 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003198 break;
3199
3200 case L2CAP_MODE_STREAMING:
3201 efs.id = 1;
3202 efs.stype = L2CAP_SERV_BESTEFFORT;
3203 efs.msdu = cpu_to_le16(chan->local_msdu);
3204 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
3205 efs.acc_lat = 0;
3206 efs.flush_to = 0;
3207 break;
3208
3209 default:
3210 return;
3211 }
3212
3213 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003214 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003215}
3216
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003217static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003218{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003219 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003220 ack_timer.work);
3221 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003222
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003223 BT_DBG("chan %p", chan);
3224
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003225 l2cap_chan_lock(chan);
3226
Mat Martineau03625202012-05-17 20:53:51 -07003227 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3228 chan->last_acked_seq);
3229
3230 if (frames_to_ack)
3231 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003232
3233 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003234 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003235}
3236
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003237int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003238{
Mat Martineau3c588192012-04-11 10:48:42 -07003239 int err;
3240
Mat Martineau105bdf92012-04-27 16:50:48 -07003241 chan->next_tx_seq = 0;
3242 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003243 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003244 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003245 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003246 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003247 chan->last_acked_seq = 0;
3248 chan->sdu = NULL;
3249 chan->sdu_last_frag = NULL;
3250 chan->sdu_len = 0;
3251
Mat Martineaud34c34f2012-05-14 14:49:27 -07003252 skb_queue_head_init(&chan->tx_q);
3253
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003254 chan->local_amp_id = AMP_ID_BREDR;
3255 chan->move_id = AMP_ID_BREDR;
Mat Martineau08333282012-10-23 15:24:06 -07003256 chan->move_state = L2CAP_MOVE_STABLE;
3257 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3258
Mat Martineau105bdf92012-04-27 16:50:48 -07003259 if (chan->mode != L2CAP_MODE_ERTM)
3260 return 0;
3261
3262 chan->rx_state = L2CAP_RX_STATE_RECV;
3263 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003264
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003265 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3266 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3267 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003268
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003269 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003270
Mat Martineau3c588192012-04-11 10:48:42 -07003271 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3272 if (err < 0)
3273 return err;
3274
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003275 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3276 if (err < 0)
3277 l2cap_seq_list_free(&chan->srej_list);
3278
3279 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003280}
3281
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003282static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3283{
3284 switch (mode) {
3285 case L2CAP_MODE_STREAMING:
3286 case L2CAP_MODE_ERTM:
3287 if (l2cap_mode_supported(mode, remote_feat_mask))
3288 return mode;
3289 /* fall through */
3290 default:
3291 return L2CAP_MODE_BASIC;
3292 }
3293}
3294
Marcel Holtmann848566b2013-10-01 22:59:22 -07003295static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003296{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003297 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003298}
3299
Marcel Holtmann848566b2013-10-01 22:59:22 -07003300static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003301{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003302 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003303}
3304
Mat Martineau36c86c82012-10-23 15:24:20 -07003305static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3306 struct l2cap_conf_rfc *rfc)
3307{
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003308 if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) {
Mat Martineau36c86c82012-10-23 15:24:20 -07003309 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3310
3311 /* Class 1 devices have must have ERTM timeouts
3312 * exceeding the Link Supervision Timeout. The
3313 * default Link Supervision Timeout for AMP
3314 * controllers is 10 seconds.
3315 *
3316 * Class 1 devices use 0xffffffff for their
3317 * best-effort flush timeout, so the clamping logic
3318 * will result in a timeout that meets the above
3319 * requirement. ERTM timeouts are 16-bit values, so
3320 * the maximum timeout is 65.535 seconds.
3321 */
3322
3323 /* Convert timeout to milliseconds and round */
3324 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3325
3326 /* This is the recommended formula for class 2 devices
3327 * that start ERTM timers when packets are sent to the
3328 * controller.
3329 */
3330 ertm_to = 3 * ertm_to + 500;
3331
3332 if (ertm_to > 0xffff)
3333 ertm_to = 0xffff;
3334
3335 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3336 rfc->monitor_timeout = rfc->retrans_timeout;
3337 } else {
3338 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3339 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3340 }
3341}
3342
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003343static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3344{
3345 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Marcel Holtmann848566b2013-10-01 22:59:22 -07003346 __l2cap_ews_supported(chan->conn)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003347 /* use extended control field */
3348 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003349 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3350 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003351 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003352 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003353 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3354 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003355 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003356}
3357
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003358static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003359{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003360 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003361 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003362 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003363 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003364
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003365 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003366
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003367 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003368 goto done;
3369
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003370 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003371 case L2CAP_MODE_STREAMING:
3372 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003373 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003374 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003375
Marcel Holtmann848566b2013-10-01 22:59:22 -07003376 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003377 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3378
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003379 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003380 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003381 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003382 break;
3383 }
3384
3385done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003386 if (chan->imtu != L2CAP_DEFAULT_MTU)
3387 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003388
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003389 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003390 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003391 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003392 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003393 break;
3394
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003395 rfc.mode = L2CAP_MODE_BASIC;
3396 rfc.txwin_size = 0;
3397 rfc.max_transmit = 0;
3398 rfc.retrans_timeout = 0;
3399 rfc.monitor_timeout = 0;
3400 rfc.max_pdu_size = 0;
3401
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003402 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003403 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003404 break;
3405
3406 case L2CAP_MODE_ERTM:
3407 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003408 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003409
3410 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003411
3412 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003413 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3414 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003415 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003416
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003417 l2cap_txwin_setup(chan);
3418
3419 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003420 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003421
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003422 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003423 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003424
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003425 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3426 l2cap_add_opt_efs(&ptr, chan);
3427
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003428 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3429 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003430 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003431
3432 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3433 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003434 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003435 chan->fcs = L2CAP_FCS_NONE;
3436 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3437 chan->fcs);
3438 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003439 break;
3440
3441 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003442 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003443 rfc.mode = L2CAP_MODE_STREAMING;
3444 rfc.txwin_size = 0;
3445 rfc.max_transmit = 0;
3446 rfc.retrans_timeout = 0;
3447 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003448
3449 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003450 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3451 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003452 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003453
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003454 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003455 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003456
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003457 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3458 l2cap_add_opt_efs(&ptr, chan);
3459
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003460 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3461 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003462 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003463 chan->fcs = L2CAP_FCS_NONE;
3464 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3465 chan->fcs);
3466 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003467 break;
3468 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003469
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003470 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003471 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003472
3473 return ptr - data;
3474}
3475
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003476static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003477{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003478 struct l2cap_conf_rsp *rsp = data;
3479 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003480 void *req = chan->conf_req;
3481 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003482 int type, hint, olen;
3483 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003484 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003485 struct l2cap_conf_efs efs;
3486 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003487 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003488 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003489 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003490
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003491 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003492
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003493 while (len >= L2CAP_CONF_OPT_SIZE) {
3494 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003495
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003496 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003497 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003498
3499 switch (type) {
3500 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003501 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003502 break;
3503
3504 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003505 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003506 break;
3507
3508 case L2CAP_CONF_QOS:
3509 break;
3510
Marcel Holtmann6464f352007-10-20 13:39:51 +02003511 case L2CAP_CONF_RFC:
3512 if (olen == sizeof(rfc))
3513 memcpy(&rfc, (void *) val, olen);
3514 break;
3515
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003516 case L2CAP_CONF_FCS:
3517 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003518 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003519 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003520
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003521 case L2CAP_CONF_EFS:
3522 remote_efs = 1;
3523 if (olen == sizeof(efs))
3524 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003525 break;
3526
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003527 case L2CAP_CONF_EWS:
Marcel Holtmann848566b2013-10-01 22:59:22 -07003528 if (!chan->conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003529 return -ECONNREFUSED;
3530
3531 set_bit(FLAG_EXT_CTRL, &chan->flags);
3532 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003533 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003534 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003535 break;
3536
3537 default:
3538 if (hint)
3539 break;
3540
3541 result = L2CAP_CONF_UNKNOWN;
3542 *((u8 *) ptr++) = type;
3543 break;
3544 }
3545 }
3546
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003547 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003548 goto done;
3549
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003550 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003551 case L2CAP_MODE_STREAMING:
3552 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003553 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003554 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003555 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003556 break;
3557 }
3558
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003559 if (remote_efs) {
Marcel Holtmann848566b2013-10-01 22:59:22 -07003560 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003561 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3562 else
3563 return -ECONNREFUSED;
3564 }
3565
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003566 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003567 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003568
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003569 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003570 }
3571
3572done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003573 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003574 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003575 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003576
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003577 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003578 return -ECONNREFUSED;
3579
Gustavo Padovan2d792812012-10-06 10:07:01 +01003580 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3581 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003582 }
3583
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003584 if (result == L2CAP_CONF_SUCCESS) {
3585 /* Configure output options and let the other side know
3586 * which ones we don't like. */
3587
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003588 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3589 result = L2CAP_CONF_UNACCEPT;
3590 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003591 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003592 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003593 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003594 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003595
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003596 if (remote_efs) {
3597 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003598 efs.stype != L2CAP_SERV_NOTRAFIC &&
3599 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003600
3601 result = L2CAP_CONF_UNACCEPT;
3602
3603 if (chan->num_conf_req >= 1)
3604 return -ECONNREFUSED;
3605
3606 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003607 sizeof(efs),
3608 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003609 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003610 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003611 result = L2CAP_CONF_PENDING;
3612 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003613 }
3614 }
3615
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003616 switch (rfc.mode) {
3617 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003618 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003619 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003620 break;
3621
3622 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003623 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3624 chan->remote_tx_win = rfc.txwin_size;
3625 else
3626 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3627
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003628 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003629
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003630 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003631 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3632 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003633 rfc.max_pdu_size = cpu_to_le16(size);
3634 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003635
Mat Martineau36c86c82012-10-23 15:24:20 -07003636 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003637
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003638 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003639
3640 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003641 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003642
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003643 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3644 chan->remote_id = efs.id;
3645 chan->remote_stype = efs.stype;
3646 chan->remote_msdu = le16_to_cpu(efs.msdu);
3647 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003648 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003649 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003650 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003651 chan->remote_sdu_itime =
3652 le32_to_cpu(efs.sdu_itime);
3653 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003654 sizeof(efs),
3655 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003656 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003657 break;
3658
3659 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003660 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003661 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3662 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003663 rfc.max_pdu_size = cpu_to_le16(size);
3664 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003665
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003666 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003667
Gustavo Padovan2d792812012-10-06 10:07:01 +01003668 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3669 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003670
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003671 break;
3672
3673 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003674 result = L2CAP_CONF_UNACCEPT;
3675
3676 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003677 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003678 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003679
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003680 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003681 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003682 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003683 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003684 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003685 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003686
3687 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003688}
3689
Gustavo Padovan2d792812012-10-06 10:07:01 +01003690static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3691 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003692{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003693 struct l2cap_conf_req *req = data;
3694 void *ptr = req->data;
3695 int type, olen;
3696 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003697 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003698 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003699
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003700 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003701
3702 while (len >= L2CAP_CONF_OPT_SIZE) {
3703 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3704
3705 switch (type) {
3706 case L2CAP_CONF_MTU:
3707 if (val < L2CAP_DEFAULT_MIN_MTU) {
3708 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003709 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003710 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003711 chan->imtu = val;
3712 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003713 break;
3714
3715 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003716 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003717 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003718 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003719 break;
3720
3721 case L2CAP_CONF_RFC:
3722 if (olen == sizeof(rfc))
3723 memcpy(&rfc, (void *)val, olen);
3724
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003725 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003726 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003727 return -ECONNREFUSED;
3728
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003729 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003730
3731 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003732 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003733 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003734
3735 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003736 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003737 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003738 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003739 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003740
3741 case L2CAP_CONF_EFS:
3742 if (olen == sizeof(efs))
3743 memcpy(&efs, (void *)val, olen);
3744
3745 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003746 efs.stype != L2CAP_SERV_NOTRAFIC &&
3747 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003748 return -ECONNREFUSED;
3749
Gustavo Padovan2d792812012-10-06 10:07:01 +01003750 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3751 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003752 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003753
3754 case L2CAP_CONF_FCS:
3755 if (*result == L2CAP_CONF_PENDING)
3756 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003757 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003758 &chan->conf_state);
3759 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003760 }
3761 }
3762
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003763 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003764 return -ECONNREFUSED;
3765
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003766 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003767
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003768 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003769 switch (rfc.mode) {
3770 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003771 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3772 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3773 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003774 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3775 chan->ack_win = min_t(u16, chan->ack_win,
3776 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003777
3778 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3779 chan->local_msdu = le16_to_cpu(efs.msdu);
3780 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003781 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003782 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3783 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003784 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003785 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003786 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003787
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003788 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003789 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003790 }
3791 }
3792
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003793 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003794 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003795
3796 return ptr - data;
3797}
3798
Gustavo Padovan2d792812012-10-06 10:07:01 +01003799static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3800 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003801{
3802 struct l2cap_conf_rsp *rsp = data;
3803 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003804
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003805 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003806
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003807 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003808 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003809 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003810
3811 return ptr - data;
3812}
3813
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03003814void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan)
3815{
3816 struct l2cap_le_conn_rsp rsp;
3817 struct l2cap_conn *conn = chan->conn;
3818
3819 BT_DBG("chan %p", chan);
3820
3821 rsp.dcid = cpu_to_le16(chan->scid);
3822 rsp.mtu = cpu_to_le16(chan->imtu);
3823 rsp.mps = __constant_cpu_to_le16(L2CAP_LE_DEFAULT_MPS);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03003824 rsp.credits = cpu_to_le16(chan->rx_credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03003825 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3826
3827 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
3828 &rsp);
3829}
3830
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003831void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003832{
3833 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003834 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003835 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003836 u8 rsp_code;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003837
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003838 rsp.scid = cpu_to_le16(chan->dcid);
3839 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003840 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3841 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003842
3843 if (chan->hs_hcon)
3844 rsp_code = L2CAP_CREATE_CHAN_RSP;
3845 else
3846 rsp_code = L2CAP_CONN_RSP;
3847
3848 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3849
3850 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003851
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003852 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003853 return;
3854
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003855 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003856 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003857 chan->num_conf_req++;
3858}
3859
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003860static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003861{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003862 int type, olen;
3863 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003864 /* Use sane default values in case a misbehaving remote device
3865 * did not send an RFC or extended window size option.
3866 */
3867 u16 txwin_ext = chan->ack_win;
3868 struct l2cap_conf_rfc rfc = {
3869 .mode = chan->mode,
3870 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3871 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3872 .max_pdu_size = cpu_to_le16(chan->imtu),
3873 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3874 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003875
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003876 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003877
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003878 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003879 return;
3880
3881 while (len >= L2CAP_CONF_OPT_SIZE) {
3882 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3883
Mat Martineauc20f8e32012-07-10 05:47:07 -07003884 switch (type) {
3885 case L2CAP_CONF_RFC:
3886 if (olen == sizeof(rfc))
3887 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003888 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003889 case L2CAP_CONF_EWS:
3890 txwin_ext = val;
3891 break;
3892 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003893 }
3894
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003895 switch (rfc.mode) {
3896 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003897 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3898 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003899 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3900 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3901 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3902 else
3903 chan->ack_win = min_t(u16, chan->ack_win,
3904 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003905 break;
3906 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003907 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003908 }
3909}
3910
Gustavo Padovan2d792812012-10-06 10:07:01 +01003911static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003912 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3913 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003914{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003915 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003916
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003917 if (cmd_len < sizeof(*rej))
3918 return -EPROTO;
3919
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003920 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003921 return 0;
3922
3923 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003924 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003925 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003926
3927 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003928 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003929
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003930 l2cap_conn_start(conn);
3931 }
3932
3933 return 0;
3934}
3935
Mat Martineau17009152012-10-23 15:24:07 -07003936static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3937 struct l2cap_cmd_hdr *cmd,
3938 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003939{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003940 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3941 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003942 struct l2cap_chan *chan = NULL, *pchan;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003943 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003944
3945 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003946 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003947
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003948 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003949
3950 /* Check if we have socket listening on psm */
Marcel Holtmann6f59b902013-10-13 05:24:01 -07003951 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03003952 &conn->hcon->dst, ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003953 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003954 result = L2CAP_CR_BAD_PSM;
3955 goto sendresp;
3956 }
3957
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003958 mutex_lock(&conn->chan_lock);
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02003959 l2cap_chan_lock(pchan);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003960
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003961 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003962 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003963 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003964 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003965 result = L2CAP_CR_SEC_BLOCK;
3966 goto response;
3967 }
3968
Linus Torvalds1da177e2005-04-16 15:20:36 -07003969 result = L2CAP_CR_NO_MEM;
3970
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003971 /* Check if we already have channel with that dcid */
3972 if (__l2cap_get_chan_by_dcid(conn, scid))
3973 goto response;
3974
Gustavo Padovan80b98022012-05-27 22:27:51 -03003975 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003976 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003977 goto response;
3978
Syam Sidhardhan330b6c12013-08-06 01:59:12 +09003979 /* For certain devices (ex: HID mouse), support for authentication,
3980 * pairing and bonding is optional. For such devices, inorder to avoid
3981 * the ACL alive for too long after L2CAP disconnection, reset the ACL
3982 * disc_timeout back to HCI_DISCONN_TIMEOUT during L2CAP connect.
3983 */
3984 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
3985
Marcel Holtmann7eafc592013-10-13 08:12:47 -07003986 bacpy(&chan->src, &conn->hcon->src);
3987 bacpy(&chan->dst, &conn->hcon->dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07003988 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
3989 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003990 chan->psm = psm;
3991 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003992 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003993
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003994 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003995
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003996 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003997
Gustavo Padovan8d836d72013-10-15 19:24:47 -03003998 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003999
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03004000 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004001
Marcel Holtmann984947d2009-02-06 23:35:19 +01004002 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02004003 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07004004 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004005 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004006 result = L2CAP_CR_PEND;
4007 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08004008 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004009 } else {
Mat Martineau17009152012-10-23 15:24:07 -07004010 /* Force pending result for AMP controllers.
4011 * The connection will succeed after the
4012 * physical link is up.
4013 */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004014 if (amp_id == AMP_ID_BREDR) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004015 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau17009152012-10-23 15:24:07 -07004016 result = L2CAP_CR_SUCCESS;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004017 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004018 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004019 result = L2CAP_CR_PEND;
Mat Martineau17009152012-10-23 15:24:07 -07004020 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004021 status = L2CAP_CS_NO_INFO;
4022 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004023 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004024 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004025 result = L2CAP_CR_PEND;
4026 status = L2CAP_CS_AUTHEN_PEND;
4027 }
4028 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004029 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004030 result = L2CAP_CR_PEND;
4031 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004032 }
4033
Linus Torvalds1da177e2005-04-16 15:20:36 -07004034response:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02004035 l2cap_chan_unlock(pchan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004036 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004037
4038sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07004039 rsp.scid = cpu_to_le16(scid);
4040 rsp.dcid = cpu_to_le16(dcid);
4041 rsp.result = cpu_to_le16(result);
4042 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03004043 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004044
4045 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
4046 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004047 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004048
4049 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
4050 conn->info_ident = l2cap_get_ident(conn);
4051
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004052 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004053
Gustavo Padovan2d792812012-10-06 10:07:01 +01004054 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
4055 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004056 }
4057
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004058 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01004059 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004060 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004061 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004062 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++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004065 }
Mat Martineau17009152012-10-23 15:24:07 -07004066
4067 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03004068}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004069
Mat Martineau4c89b6a2012-10-11 17:48:22 +03004070static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004071 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03004072{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05304073 struct hci_dev *hdev = conn->hcon->hdev;
4074 struct hci_conn *hcon = conn->hcon;
4075
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004076 if (cmd_len < sizeof(struct l2cap_conn_req))
4077 return -EPROTO;
4078
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05304079 hci_dev_lock(hdev);
4080 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
4081 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
4082 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
4083 hcon->dst_type, 0, NULL, 0,
4084 hcon->dev_class);
4085 hci_dev_unlock(hdev);
4086
Gustavo Padovan300229f2012-10-12 19:40:40 +08004087 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004088 return 0;
4089}
4090
Mat Martineau5909cf32012-10-23 15:24:08 -07004091static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004092 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4093 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004094{
4095 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
4096 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004097 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004098 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004099 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004100
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004101 if (cmd_len < sizeof(*rsp))
4102 return -EPROTO;
4103
Linus Torvalds1da177e2005-04-16 15:20:36 -07004104 scid = __le16_to_cpu(rsp->scid);
4105 dcid = __le16_to_cpu(rsp->dcid);
4106 result = __le16_to_cpu(rsp->result);
4107 status = __le16_to_cpu(rsp->status);
4108
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02004109 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 +01004110 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004111
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004112 mutex_lock(&conn->chan_lock);
4113
Linus Torvalds1da177e2005-04-16 15:20:36 -07004114 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004115 chan = __l2cap_get_chan_by_scid(conn, scid);
4116 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03004117 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004118 goto unlock;
4119 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004120 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004121 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
4122 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03004123 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004124 goto unlock;
4125 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004126 }
4127
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004128 err = 0;
4129
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004130 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004131
Linus Torvalds1da177e2005-04-16 15:20:36 -07004132 switch (result) {
4133 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03004134 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03004135 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004136 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004137 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004138
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004139 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004140 break;
4141
Linus Torvalds1da177e2005-04-16 15:20:36 -07004142 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004143 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004144 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004145 break;
4146
4147 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004148 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004149 break;
4150
4151 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004152 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004153 break;
4154 }
4155
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004156 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004157
4158unlock:
4159 mutex_unlock(&conn->chan_lock);
4160
4161 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004162}
4163
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004164static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07004165{
4166 /* FCS is enabled only in ERTM or streaming mode, if one or both
4167 * sides request it.
4168 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03004169 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004170 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02004171 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004172 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07004173}
4174
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004175static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
4176 u8 ident, u16 flags)
4177{
4178 struct l2cap_conn *conn = chan->conn;
4179
4180 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
4181 flags);
4182
4183 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
4184 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
4185
4186 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
4187 l2cap_build_conf_rsp(chan, data,
4188 L2CAP_CONF_SUCCESS, flags), data);
4189}
4190
Johan Hedberg662d6522013-10-16 11:20:47 +03004191static void cmd_reject_invalid_cid(struct l2cap_conn *conn, u8 ident,
4192 u16 scid, u16 dcid)
4193{
4194 struct l2cap_cmd_rej_cid rej;
4195
4196 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
4197 rej.scid = __cpu_to_le16(scid);
4198 rej.dcid = __cpu_to_le16(dcid);
4199
4200 l2cap_send_cmd(conn, ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
4201}
4202
Gustavo Padovan2d792812012-10-06 10:07:01 +01004203static inline int l2cap_config_req(struct l2cap_conn *conn,
4204 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4205 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004206{
4207 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
4208 u16 dcid, flags;
4209 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004210 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07004211 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004212
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004213 if (cmd_len < sizeof(*req))
4214 return -EPROTO;
4215
Linus Torvalds1da177e2005-04-16 15:20:36 -07004216 dcid = __le16_to_cpu(req->dcid);
4217 flags = __le16_to_cpu(req->flags);
4218
4219 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
4220
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004221 chan = l2cap_get_chan_by_scid(conn, dcid);
Johan Hedberg662d6522013-10-16 11:20:47 +03004222 if (!chan) {
4223 cmd_reject_invalid_cid(conn, cmd->ident, dcid, 0);
4224 return 0;
4225 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004226
David S. Miller033b1142011-07-21 13:38:42 -07004227 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Johan Hedberg662d6522013-10-16 11:20:47 +03004228 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4229 chan->dcid);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004230 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004231 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004232
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004233 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07004234 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004235 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004236 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004237 l2cap_build_conf_rsp(chan, rsp,
4238 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004239 goto unlock;
4240 }
4241
4242 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004243 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4244 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004245
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004246 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004247 /* Incomplete config. Send empty response. */
4248 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004249 l2cap_build_conf_rsp(chan, rsp,
4250 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004251 goto unlock;
4252 }
4253
4254 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004255 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004256 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004257 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004258 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004259 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004260
Mat Martineau1500109b2012-10-23 15:24:15 -07004261 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004262 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004263 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004264
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004265 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004266 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004267
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004268 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004269 goto unlock;
4270
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004271 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004272 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004273
Mat Martineau105bdf92012-04-27 16:50:48 -07004274 if (chan->mode == L2CAP_MODE_ERTM ||
4275 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004276 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004277
Mat Martineau3c588192012-04-11 10:48:42 -07004278 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004279 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004280 else
4281 l2cap_chan_ready(chan);
4282
Marcel Holtmann876d9482007-10-20 13:35:42 +02004283 goto unlock;
4284 }
4285
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004286 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004287 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004288 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004289 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004290 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004291 }
4292
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004293 /* Got Conf Rsp PENDING from remote side and asume we sent
4294 Conf Rsp PENDING in the code above */
4295 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004296 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004297
4298 /* check compatibility */
4299
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004300 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004301 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004302 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4303 else
4304 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004305 }
4306
Linus Torvalds1da177e2005-04-16 15:20:36 -07004307unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004308 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004309 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004310}
4311
Gustavo Padovan2d792812012-10-06 10:07:01 +01004312static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004313 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4314 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004315{
4316 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4317 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004318 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004319 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004320 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004321
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004322 if (cmd_len < sizeof(*rsp))
4323 return -EPROTO;
4324
Linus Torvalds1da177e2005-04-16 15:20:36 -07004325 scid = __le16_to_cpu(rsp->scid);
4326 flags = __le16_to_cpu(rsp->flags);
4327 result = __le16_to_cpu(rsp->result);
4328
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004329 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4330 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004331
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004332 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004333 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004334 return 0;
4335
4336 switch (result) {
4337 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004338 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004339 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004340 break;
4341
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004342 case L2CAP_CONF_PENDING:
4343 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4344
4345 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4346 char buf[64];
4347
4348 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004349 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004350 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004351 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004352 goto done;
4353 }
4354
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004355 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004356 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4357 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004358 } else {
4359 if (l2cap_check_efs(chan)) {
4360 amp_create_logical_link(chan);
4361 chan->ident = cmd->ident;
4362 }
4363 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004364 }
4365 goto done;
4366
Linus Torvalds1da177e2005-04-16 15:20:36 -07004367 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004368 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004369 char req[64];
4370
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004371 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004372 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004373 goto done;
4374 }
4375
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004376 /* throw out any old stored conf requests */
4377 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004378 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004379 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004380 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004381 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004382 goto done;
4383 }
4384
4385 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004386 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004387 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004388 if (result != L2CAP_CONF_SUCCESS)
4389 goto done;
4390 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004391 }
4392
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004393 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004394 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004395
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004396 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004397 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004398 goto done;
4399 }
4400
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004401 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004402 goto done;
4403
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004404 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004405
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004406 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004407 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004408
Mat Martineau105bdf92012-04-27 16:50:48 -07004409 if (chan->mode == L2CAP_MODE_ERTM ||
4410 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004411 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004412
Mat Martineau3c588192012-04-11 10:48:42 -07004413 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004414 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004415 else
4416 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004417 }
4418
4419done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004420 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004421 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004422}
4423
Gustavo Padovan2d792812012-10-06 10:07:01 +01004424static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004425 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4426 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004427{
4428 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4429 struct l2cap_disconn_rsp rsp;
4430 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004431 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004432
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004433 if (cmd_len != sizeof(*req))
4434 return -EPROTO;
4435
Linus Torvalds1da177e2005-04-16 15:20:36 -07004436 scid = __le16_to_cpu(req->scid);
4437 dcid = __le16_to_cpu(req->dcid);
4438
4439 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4440
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004441 mutex_lock(&conn->chan_lock);
4442
4443 chan = __l2cap_get_chan_by_scid(conn, dcid);
4444 if (!chan) {
4445 mutex_unlock(&conn->chan_lock);
Johan Hedberg662d6522013-10-16 11:20:47 +03004446 cmd_reject_invalid_cid(conn, cmd->ident, dcid, scid);
4447 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004448 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004449
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004450 l2cap_chan_lock(chan);
4451
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004452 rsp.dcid = cpu_to_le16(chan->scid);
4453 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004454 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4455
Gustavo Padovan5ec1bbe2013-10-15 19:24:48 -03004456 chan->ops->set_shutdown(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004457
Mat Martineau61d6ef32012-04-27 16:50:50 -07004458 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004459 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004460
4461 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004462
Gustavo Padovan80b98022012-05-27 22:27:51 -03004463 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004464 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004465
4466 mutex_unlock(&conn->chan_lock);
4467
Linus Torvalds1da177e2005-04-16 15:20:36 -07004468 return 0;
4469}
4470
Gustavo Padovan2d792812012-10-06 10:07:01 +01004471static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004472 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4473 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004474{
4475 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4476 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004477 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004478
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004479 if (cmd_len != sizeof(*rsp))
4480 return -EPROTO;
4481
Linus Torvalds1da177e2005-04-16 15:20:36 -07004482 scid = __le16_to_cpu(rsp->scid);
4483 dcid = __le16_to_cpu(rsp->dcid);
4484
4485 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4486
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004487 mutex_lock(&conn->chan_lock);
4488
4489 chan = __l2cap_get_chan_by_scid(conn, scid);
4490 if (!chan) {
4491 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004492 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004493 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004494
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004495 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004496
Mat Martineau61d6ef32012-04-27 16:50:50 -07004497 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004498 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004499
4500 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004501
Gustavo Padovan80b98022012-05-27 22:27:51 -03004502 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004503 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004504
4505 mutex_unlock(&conn->chan_lock);
4506
Linus Torvalds1da177e2005-04-16 15:20:36 -07004507 return 0;
4508}
4509
Gustavo Padovan2d792812012-10-06 10:07:01 +01004510static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004511 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4512 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004513{
4514 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004515 u16 type;
4516
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004517 if (cmd_len != sizeof(*req))
4518 return -EPROTO;
4519
Linus Torvalds1da177e2005-04-16 15:20:36 -07004520 type = __le16_to_cpu(req->type);
4521
4522 BT_DBG("type 0x%4.4x", type);
4523
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004524 if (type == L2CAP_IT_FEAT_MASK) {
4525 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004526 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004527 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004528 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4529 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004530 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004531 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004532 | L2CAP_FEAT_FCS;
Marcel Holtmann848566b2013-10-01 22:59:22 -07004533 if (conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004534 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004535 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004536
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004537 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004538 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4539 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004540 } else if (type == L2CAP_IT_FIXED_CHAN) {
4541 u8 buf[12];
4542 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004543
Marcel Holtmann848566b2013-10-01 22:59:22 -07004544 if (conn->hs_enabled)
Mat Martineau50a147c2011-11-02 16:18:34 -07004545 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4546 else
4547 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4548
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004549 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4550 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004551 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004552 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4553 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004554 } else {
4555 struct l2cap_info_rsp rsp;
4556 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004557 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004558 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4559 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004560 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004561
4562 return 0;
4563}
4564
Gustavo Padovan2d792812012-10-06 10:07:01 +01004565static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004566 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4567 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004568{
4569 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4570 u16 type, result;
4571
Jaganath Kanakkassery3f6fa3d2013-06-21 19:55:11 +05304572 if (cmd_len < sizeof(*rsp))
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004573 return -EPROTO;
4574
Linus Torvalds1da177e2005-04-16 15:20:36 -07004575 type = __le16_to_cpu(rsp->type);
4576 result = __le16_to_cpu(rsp->result);
4577
4578 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4579
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004580 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4581 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004582 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004583 return 0;
4584
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004585 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004586
Ville Tervoadb08ed2010-08-04 09:43:33 +03004587 if (result != L2CAP_IR_SUCCESS) {
4588 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4589 conn->info_ident = 0;
4590
4591 l2cap_conn_start(conn);
4592
4593 return 0;
4594 }
4595
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004596 switch (type) {
4597 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004598 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004599
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004600 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004601 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004602 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004603
4604 conn->info_ident = l2cap_get_ident(conn);
4605
4606 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004607 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004608 } else {
4609 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4610 conn->info_ident = 0;
4611
4612 l2cap_conn_start(conn);
4613 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004614 break;
4615
4616 case L2CAP_IT_FIXED_CHAN:
4617 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004618 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004619 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004620
4621 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004622 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004623 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004624
Linus Torvalds1da177e2005-04-16 15:20:36 -07004625 return 0;
4626}
4627
Mat Martineau17009152012-10-23 15:24:07 -07004628static int l2cap_create_channel_req(struct l2cap_conn *conn,
4629 struct l2cap_cmd_hdr *cmd,
4630 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004631{
4632 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004633 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004634 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004635 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004636 u16 psm, scid;
4637
4638 if (cmd_len != sizeof(*req))
4639 return -EPROTO;
4640
Marcel Holtmann848566b2013-10-01 22:59:22 -07004641 if (!conn->hs_enabled)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004642 return -EINVAL;
4643
4644 psm = le16_to_cpu(req->psm);
4645 scid = le16_to_cpu(req->scid);
4646
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004647 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 -07004648
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004649 /* For controller id 0 make BR/EDR connection */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004650 if (req->amp_id == AMP_ID_BREDR) {
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004651 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4652 req->amp_id);
4653 return 0;
4654 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004655
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004656 /* Validate AMP controller id */
4657 hdev = hci_dev_get(req->amp_id);
4658 if (!hdev)
4659 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004660
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004661 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004662 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004663 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004664 }
4665
4666 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4667 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004668 if (chan) {
4669 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4670 struct hci_conn *hs_hcon;
4671
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07004672 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
4673 &conn->hcon->dst);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004674 if (!hs_hcon) {
4675 hci_dev_put(hdev);
Johan Hedberg662d6522013-10-16 11:20:47 +03004676 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4677 chan->dcid);
4678 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004679 }
4680
4681 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4682
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004683 mgr->bredr_chan = chan;
4684 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004685 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004686 conn->mtu = hdev->block_mtu;
4687 }
4688
4689 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004690
4691 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004692
4693error:
4694 rsp.dcid = 0;
4695 rsp.scid = cpu_to_le16(scid);
4696 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4697 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4698
4699 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4700 sizeof(rsp), &rsp);
4701
Johan Hedbergdc280802013-09-16 13:05:13 +03004702 return 0;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004703}
4704
Mat Martineau8eb200b2012-10-23 15:24:17 -07004705static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4706{
4707 struct l2cap_move_chan_req req;
4708 u8 ident;
4709
4710 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4711
4712 ident = l2cap_get_ident(chan->conn);
4713 chan->ident = ident;
4714
4715 req.icid = cpu_to_le16(chan->scid);
4716 req.dest_amp_id = dest_amp_id;
4717
4718 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4719 &req);
4720
4721 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4722}
4723
Mat Martineau1500109b2012-10-23 15:24:15 -07004724static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004725{
4726 struct l2cap_move_chan_rsp rsp;
4727
Mat Martineau1500109b2012-10-23 15:24:15 -07004728 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004729
Mat Martineau1500109b2012-10-23 15:24:15 -07004730 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004731 rsp.result = cpu_to_le16(result);
4732
Mat Martineau1500109b2012-10-23 15:24:15 -07004733 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4734 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004735}
4736
Mat Martineau5b155ef2012-10-23 15:24:14 -07004737static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004738{
4739 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004740
Mat Martineau5b155ef2012-10-23 15:24:14 -07004741 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004742
Mat Martineau5b155ef2012-10-23 15:24:14 -07004743 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004744
Mat Martineau5b155ef2012-10-23 15:24:14 -07004745 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004746 cfm.result = cpu_to_le16(result);
4747
Mat Martineau5b155ef2012-10-23 15:24:14 -07004748 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4749 sizeof(cfm), &cfm);
4750
4751 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4752}
4753
4754static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4755{
4756 struct l2cap_move_chan_cfm cfm;
4757
4758 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4759
4760 cfm.icid = cpu_to_le16(icid);
4761 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4762
4763 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4764 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004765}
4766
4767static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004768 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004769{
4770 struct l2cap_move_chan_cfm_rsp rsp;
4771
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004772 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004773
4774 rsp.icid = cpu_to_le16(icid);
4775 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4776}
4777
Mat Martineau5f3847a2012-10-23 15:24:12 -07004778static void __release_logical_link(struct l2cap_chan *chan)
4779{
4780 chan->hs_hchan = NULL;
4781 chan->hs_hcon = NULL;
4782
4783 /* Placeholder - release the logical link */
4784}
4785
Mat Martineau1500109b2012-10-23 15:24:15 -07004786static void l2cap_logical_fail(struct l2cap_chan *chan)
4787{
4788 /* Logical link setup failed */
4789 if (chan->state != BT_CONNECTED) {
4790 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004791 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004792 return;
4793 }
4794
4795 switch (chan->move_role) {
4796 case L2CAP_MOVE_ROLE_RESPONDER:
4797 l2cap_move_done(chan);
4798 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4799 break;
4800 case L2CAP_MOVE_ROLE_INITIATOR:
4801 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4802 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4803 /* Remote has only sent pending or
4804 * success responses, clean up
4805 */
4806 l2cap_move_done(chan);
4807 }
4808
4809 /* Other amp move states imply that the move
4810 * has already aborted
4811 */
4812 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4813 break;
4814 }
4815}
4816
4817static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4818 struct hci_chan *hchan)
4819{
4820 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004821
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004822 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004823 chan->hs_hcon->l2cap_data = chan->conn;
4824
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004825 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004826
4827 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004828 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004829
4830 set_default_fcs(chan);
4831
4832 err = l2cap_ertm_init(chan);
4833 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004834 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004835 else
4836 l2cap_chan_ready(chan);
4837 }
4838}
4839
4840static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4841 struct hci_chan *hchan)
4842{
4843 chan->hs_hcon = hchan->conn;
4844 chan->hs_hcon->l2cap_data = chan->conn;
4845
4846 BT_DBG("move_state %d", chan->move_state);
4847
4848 switch (chan->move_state) {
4849 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4850 /* Move confirm will be sent after a success
4851 * response is received
4852 */
4853 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4854 break;
4855 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4856 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4857 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4858 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4859 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4860 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4861 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4862 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4863 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4864 }
4865 break;
4866 default:
4867 /* Move was not in expected state, free the channel */
4868 __release_logical_link(chan);
4869
4870 chan->move_state = L2CAP_MOVE_STABLE;
4871 }
4872}
4873
4874/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004875void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4876 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004877{
Mat Martineau1500109b2012-10-23 15:24:15 -07004878 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4879
4880 if (status) {
4881 l2cap_logical_fail(chan);
4882 __release_logical_link(chan);
4883 return;
4884 }
4885
4886 if (chan->state != BT_CONNECTED) {
4887 /* Ignore logical link if channel is on BR/EDR */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004888 if (chan->local_amp_id != AMP_ID_BREDR)
Mat Martineau1500109b2012-10-23 15:24:15 -07004889 l2cap_logical_finish_create(chan, hchan);
4890 } else {
4891 l2cap_logical_finish_move(chan, hchan);
4892 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004893}
4894
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004895void l2cap_move_start(struct l2cap_chan *chan)
4896{
4897 BT_DBG("chan %p", chan);
4898
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004899 if (chan->local_amp_id == AMP_ID_BREDR) {
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004900 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4901 return;
4902 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4903 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4904 /* Placeholder - start physical link setup */
4905 } else {
4906 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4907 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4908 chan->move_id = 0;
4909 l2cap_move_setup(chan);
4910 l2cap_send_move_chan_req(chan, 0);
4911 }
4912}
4913
Mat Martineau8eb200b2012-10-23 15:24:17 -07004914static void l2cap_do_create(struct l2cap_chan *chan, int result,
4915 u8 local_amp_id, u8 remote_amp_id)
4916{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004917 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4918 local_amp_id, remote_amp_id);
4919
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004920 chan->fcs = L2CAP_FCS_NONE;
4921
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004922 /* Outgoing channel on AMP */
4923 if (chan->state == BT_CONNECT) {
4924 if (result == L2CAP_CR_SUCCESS) {
4925 chan->local_amp_id = local_amp_id;
4926 l2cap_send_create_chan_req(chan, remote_amp_id);
4927 } else {
4928 /* Revert to BR/EDR connect */
4929 l2cap_send_conn_req(chan);
4930 }
4931
4932 return;
4933 }
4934
4935 /* Incoming channel on AMP */
4936 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004937 struct l2cap_conn_rsp rsp;
4938 char buf[128];
4939 rsp.scid = cpu_to_le16(chan->dcid);
4940 rsp.dcid = cpu_to_le16(chan->scid);
4941
Mat Martineau8eb200b2012-10-23 15:24:17 -07004942 if (result == L2CAP_CR_SUCCESS) {
4943 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004944 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4945 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004946 } else {
4947 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004948 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4949 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004950 }
4951
4952 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4953 sizeof(rsp), &rsp);
4954
4955 if (result == L2CAP_CR_SUCCESS) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004956 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004957 set_bit(CONF_REQ_SENT, &chan->conf_state);
4958 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4959 L2CAP_CONF_REQ,
4960 l2cap_build_conf_req(chan, buf), buf);
4961 chan->num_conf_req++;
4962 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004963 }
4964}
4965
4966static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4967 u8 remote_amp_id)
4968{
4969 l2cap_move_setup(chan);
4970 chan->move_id = local_amp_id;
4971 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4972
4973 l2cap_send_move_chan_req(chan, remote_amp_id);
4974}
4975
4976static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4977{
4978 struct hci_chan *hchan = NULL;
4979
4980 /* Placeholder - get hci_chan for logical link */
4981
4982 if (hchan) {
4983 if (hchan->state == BT_CONNECTED) {
4984 /* Logical link is ready to go */
4985 chan->hs_hcon = hchan->conn;
4986 chan->hs_hcon->l2cap_data = chan->conn;
4987 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4988 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4989
4990 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4991 } else {
4992 /* Wait for logical link to be ready */
4993 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4994 }
4995 } else {
4996 /* Logical link not available */
4997 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4998 }
4999}
5000
5001static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
5002{
5003 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
5004 u8 rsp_result;
5005 if (result == -EINVAL)
5006 rsp_result = L2CAP_MR_BAD_ID;
5007 else
5008 rsp_result = L2CAP_MR_NOT_ALLOWED;
5009
5010 l2cap_send_move_chan_rsp(chan, rsp_result);
5011 }
5012
5013 chan->move_role = L2CAP_MOVE_ROLE_NONE;
5014 chan->move_state = L2CAP_MOVE_STABLE;
5015
5016 /* Restart data transmission */
5017 l2cap_ertm_send(chan);
5018}
5019
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02005020/* Invoke with locked chan */
5021void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07005022{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02005023 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02005024 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02005025
Mat Martineau8eb200b2012-10-23 15:24:17 -07005026 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
5027 chan, result, local_amp_id, remote_amp_id);
5028
Mat Martineau8eb200b2012-10-23 15:24:17 -07005029 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
5030 l2cap_chan_unlock(chan);
5031 return;
5032 }
5033
5034 if (chan->state != BT_CONNECTED) {
5035 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
5036 } else if (result != L2CAP_MR_SUCCESS) {
5037 l2cap_do_move_cancel(chan, result);
5038 } else {
5039 switch (chan->move_role) {
5040 case L2CAP_MOVE_ROLE_INITIATOR:
5041 l2cap_do_move_initiate(chan, local_amp_id,
5042 remote_amp_id);
5043 break;
5044 case L2CAP_MOVE_ROLE_RESPONDER:
5045 l2cap_do_move_respond(chan, result);
5046 break;
5047 default:
5048 l2cap_do_move_cancel(chan, result);
5049 break;
5050 }
5051 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07005052}
5053
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005054static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005055 struct l2cap_cmd_hdr *cmd,
5056 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005057{
5058 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07005059 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005060 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005061 u16 icid = 0;
5062 u16 result = L2CAP_MR_NOT_ALLOWED;
5063
5064 if (cmd_len != sizeof(*req))
5065 return -EPROTO;
5066
5067 icid = le16_to_cpu(req->icid);
5068
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005069 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005070
Marcel Holtmann848566b2013-10-01 22:59:22 -07005071 if (!conn->hs_enabled)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005072 return -EINVAL;
5073
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005074 chan = l2cap_get_chan_by_dcid(conn, icid);
5075 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07005076 rsp.icid = cpu_to_le16(icid);
5077 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
5078 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
5079 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005080 return 0;
5081 }
5082
Mat Martineau1500109b2012-10-23 15:24:15 -07005083 chan->ident = cmd->ident;
5084
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005085 if (chan->scid < L2CAP_CID_DYN_START ||
5086 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
5087 (chan->mode != L2CAP_MODE_ERTM &&
5088 chan->mode != L2CAP_MODE_STREAMING)) {
5089 result = L2CAP_MR_NOT_ALLOWED;
5090 goto send_move_response;
5091 }
5092
5093 if (chan->local_amp_id == req->dest_amp_id) {
5094 result = L2CAP_MR_SAME_ID;
5095 goto send_move_response;
5096 }
5097
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005098 if (req->dest_amp_id != AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005099 struct hci_dev *hdev;
5100 hdev = hci_dev_get(req->dest_amp_id);
5101 if (!hdev || hdev->dev_type != HCI_AMP ||
5102 !test_bit(HCI_UP, &hdev->flags)) {
5103 if (hdev)
5104 hci_dev_put(hdev);
5105
5106 result = L2CAP_MR_BAD_ID;
5107 goto send_move_response;
5108 }
5109 hci_dev_put(hdev);
5110 }
5111
5112 /* Detect a move collision. Only send a collision response
5113 * if this side has "lost", otherwise proceed with the move.
5114 * The winner has the larger bd_addr.
5115 */
5116 if ((__chan_is_moving(chan) ||
5117 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
Marcel Holtmann6f59b902013-10-13 05:24:01 -07005118 bacmp(&conn->hcon->src, &conn->hcon->dst) > 0) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005119 result = L2CAP_MR_COLLISION;
5120 goto send_move_response;
5121 }
5122
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005123 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5124 l2cap_move_setup(chan);
5125 chan->move_id = req->dest_amp_id;
5126 icid = chan->dcid;
5127
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005128 if (req->dest_amp_id == AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005129 /* Moving to BR/EDR */
5130 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5131 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
5132 result = L2CAP_MR_PEND;
5133 } else {
5134 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
5135 result = L2CAP_MR_SUCCESS;
5136 }
5137 } else {
5138 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
5139 /* Placeholder - uncomment when amp functions are available */
5140 /*amp_accept_physical(chan, req->dest_amp_id);*/
5141 result = L2CAP_MR_PEND;
5142 }
5143
5144send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07005145 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005146
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005147 l2cap_chan_unlock(chan);
5148
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005149 return 0;
5150}
5151
Mat Martineau5b155ef2012-10-23 15:24:14 -07005152static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
5153{
5154 struct l2cap_chan *chan;
5155 struct hci_chan *hchan = NULL;
5156
5157 chan = l2cap_get_chan_by_scid(conn, icid);
5158 if (!chan) {
5159 l2cap_send_move_chan_cfm_icid(conn, icid);
5160 return;
5161 }
5162
5163 __clear_chan_timer(chan);
5164 if (result == L2CAP_MR_PEND)
5165 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
5166
5167 switch (chan->move_state) {
5168 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
5169 /* Move confirm will be sent when logical link
5170 * is complete.
5171 */
5172 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5173 break;
5174 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
5175 if (result == L2CAP_MR_PEND) {
5176 break;
5177 } else if (test_bit(CONN_LOCAL_BUSY,
5178 &chan->conn_state)) {
5179 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
5180 } else {
5181 /* Logical link is up or moving to BR/EDR,
5182 * proceed with move
5183 */
5184 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
5185 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5186 }
5187 break;
5188 case L2CAP_MOVE_WAIT_RSP:
5189 /* Moving to AMP */
5190 if (result == L2CAP_MR_SUCCESS) {
5191 /* Remote is ready, send confirm immediately
5192 * after logical link is ready
5193 */
5194 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5195 } else {
5196 /* Both logical link and move success
5197 * are required to confirm
5198 */
5199 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
5200 }
5201
5202 /* Placeholder - get hci_chan for logical link */
5203 if (!hchan) {
5204 /* Logical link not available */
5205 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5206 break;
5207 }
5208
5209 /* If the logical link is not yet connected, do not
5210 * send confirmation.
5211 */
5212 if (hchan->state != BT_CONNECTED)
5213 break;
5214
5215 /* Logical link is already ready to go */
5216
5217 chan->hs_hcon = hchan->conn;
5218 chan->hs_hcon->l2cap_data = chan->conn;
5219
5220 if (result == L2CAP_MR_SUCCESS) {
5221 /* Can confirm now */
5222 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5223 } else {
5224 /* Now only need move success
5225 * to confirm
5226 */
5227 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
5228 }
5229
5230 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5231 break;
5232 default:
5233 /* Any other amp move state means the move failed. */
5234 chan->move_id = chan->local_amp_id;
5235 l2cap_move_done(chan);
5236 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5237 }
5238
5239 l2cap_chan_unlock(chan);
5240}
5241
5242static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5243 u16 result)
5244{
5245 struct l2cap_chan *chan;
5246
5247 chan = l2cap_get_chan_by_ident(conn, ident);
5248 if (!chan) {
5249 /* Could not locate channel, icid is best guess */
5250 l2cap_send_move_chan_cfm_icid(conn, icid);
5251 return;
5252 }
5253
5254 __clear_chan_timer(chan);
5255
5256 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5257 if (result == L2CAP_MR_COLLISION) {
5258 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5259 } else {
5260 /* Cleanup - cancel move */
5261 chan->move_id = chan->local_amp_id;
5262 l2cap_move_done(chan);
5263 }
5264 }
5265
5266 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5267
5268 l2cap_chan_unlock(chan);
5269}
5270
5271static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5272 struct l2cap_cmd_hdr *cmd,
5273 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005274{
5275 struct l2cap_move_chan_rsp *rsp = data;
5276 u16 icid, result;
5277
5278 if (cmd_len != sizeof(*rsp))
5279 return -EPROTO;
5280
5281 icid = le16_to_cpu(rsp->icid);
5282 result = le16_to_cpu(rsp->result);
5283
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005284 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005285
Mat Martineau5b155ef2012-10-23 15:24:14 -07005286 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5287 l2cap_move_continue(conn, icid, result);
5288 else
5289 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005290
5291 return 0;
5292}
5293
Mat Martineau5f3847a2012-10-23 15:24:12 -07005294static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5295 struct l2cap_cmd_hdr *cmd,
5296 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005297{
5298 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005299 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005300 u16 icid, result;
5301
5302 if (cmd_len != sizeof(*cfm))
5303 return -EPROTO;
5304
5305 icid = le16_to_cpu(cfm->icid);
5306 result = le16_to_cpu(cfm->result);
5307
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005308 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005309
Mat Martineau5f3847a2012-10-23 15:24:12 -07005310 chan = l2cap_get_chan_by_dcid(conn, icid);
5311 if (!chan) {
5312 /* Spec requires a response even if the icid was not found */
5313 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5314 return 0;
5315 }
5316
5317 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5318 if (result == L2CAP_MC_CONFIRMED) {
5319 chan->local_amp_id = chan->move_id;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005320 if (chan->local_amp_id == AMP_ID_BREDR)
Mat Martineau5f3847a2012-10-23 15:24:12 -07005321 __release_logical_link(chan);
5322 } else {
5323 chan->move_id = chan->local_amp_id;
5324 }
5325
5326 l2cap_move_done(chan);
5327 }
5328
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005329 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5330
Mat Martineau5f3847a2012-10-23 15:24:12 -07005331 l2cap_chan_unlock(chan);
5332
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005333 return 0;
5334}
5335
5336static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005337 struct l2cap_cmd_hdr *cmd,
5338 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005339{
5340 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005341 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005342 u16 icid;
5343
5344 if (cmd_len != sizeof(*rsp))
5345 return -EPROTO;
5346
5347 icid = le16_to_cpu(rsp->icid);
5348
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005349 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005350
Mat Martineau3fd71a02012-10-23 15:24:16 -07005351 chan = l2cap_get_chan_by_scid(conn, icid);
5352 if (!chan)
5353 return 0;
5354
5355 __clear_chan_timer(chan);
5356
5357 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5358 chan->local_amp_id = chan->move_id;
5359
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005360 if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan)
Mat Martineau3fd71a02012-10-23 15:24:16 -07005361 __release_logical_link(chan);
5362
5363 l2cap_move_done(chan);
5364 }
5365
5366 l2cap_chan_unlock(chan);
5367
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005368 return 0;
5369}
5370
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005371static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005372 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005373{
5374 u16 max_latency;
5375
5376 if (min > max || min < 6 || max > 3200)
5377 return -EINVAL;
5378
5379 if (to_multiplier < 10 || to_multiplier > 3200)
5380 return -EINVAL;
5381
5382 if (max >= to_multiplier * 8)
5383 return -EINVAL;
5384
5385 max_latency = (to_multiplier * 8 / max) - 1;
5386 if (latency > 499 || latency > max_latency)
5387 return -EINVAL;
5388
5389 return 0;
5390}
5391
5392static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005393 struct l2cap_cmd_hdr *cmd,
Johan Hedberg203e6392013-05-15 10:07:15 +03005394 u16 cmd_len, u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005395{
5396 struct hci_conn *hcon = conn->hcon;
5397 struct l2cap_conn_param_update_req *req;
5398 struct l2cap_conn_param_update_rsp rsp;
Johan Hedberg203e6392013-05-15 10:07:15 +03005399 u16 min, max, latency, to_multiplier;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005400 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005401
5402 if (!(hcon->link_mode & HCI_LM_MASTER))
5403 return -EINVAL;
5404
Claudio Takahaside731152011-02-11 19:28:55 -02005405 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5406 return -EPROTO;
5407
5408 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005409 min = __le16_to_cpu(req->min);
5410 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005411 latency = __le16_to_cpu(req->latency);
5412 to_multiplier = __le16_to_cpu(req->to_multiplier);
5413
5414 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 +01005415 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005416
5417 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005418
5419 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5420 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005421 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005422 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005423 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005424
5425 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005426 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005427
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005428 if (!err)
5429 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5430
Claudio Takahaside731152011-02-11 19:28:55 -02005431 return 0;
5432}
5433
Johan Hedbergf1496de2013-05-13 14:15:56 +03005434static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
5435 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5436 u8 *data)
5437{
5438 struct l2cap_le_conn_rsp *rsp = (struct l2cap_le_conn_rsp *) data;
5439 u16 dcid, mtu, mps, credits, result;
5440 struct l2cap_chan *chan;
5441 int err;
5442
5443 if (cmd_len < sizeof(*rsp))
5444 return -EPROTO;
5445
5446 dcid = __le16_to_cpu(rsp->dcid);
5447 mtu = __le16_to_cpu(rsp->mtu);
5448 mps = __le16_to_cpu(rsp->mps);
5449 credits = __le16_to_cpu(rsp->credits);
5450 result = __le16_to_cpu(rsp->result);
5451
5452 if (result == L2CAP_CR_SUCCESS && (mtu < 23 || mps < 23))
5453 return -EPROTO;
5454
5455 BT_DBG("dcid 0x%4.4x mtu %u mps %u credits %u result 0x%2.2x",
5456 dcid, mtu, mps, credits, result);
5457
5458 mutex_lock(&conn->chan_lock);
5459
5460 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
5461 if (!chan) {
5462 err = -EBADSLT;
5463 goto unlock;
5464 }
5465
5466 err = 0;
5467
5468 l2cap_chan_lock(chan);
5469
5470 switch (result) {
5471 case L2CAP_CR_SUCCESS:
5472 chan->ident = 0;
5473 chan->dcid = dcid;
5474 chan->omtu = mtu;
5475 chan->remote_mps = mps;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005476 chan->tx_credits = credits;
Johan Hedbergf1496de2013-05-13 14:15:56 +03005477 l2cap_chan_ready(chan);
5478 break;
5479
5480 default:
5481 l2cap_chan_del(chan, ECONNREFUSED);
5482 break;
5483 }
5484
5485 l2cap_chan_unlock(chan);
5486
5487unlock:
5488 mutex_unlock(&conn->chan_lock);
5489
5490 return err;
5491}
5492
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005493static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005494 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5495 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005496{
5497 int err = 0;
5498
5499 switch (cmd->code) {
5500 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005501 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005502 break;
5503
5504 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005505 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005506 break;
5507
5508 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005509 case L2CAP_CREATE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005510 l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005511 break;
5512
5513 case L2CAP_CONF_REQ:
5514 err = l2cap_config_req(conn, cmd, cmd_len, data);
5515 break;
5516
5517 case L2CAP_CONF_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005518 l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005519 break;
5520
5521 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005522 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005523 break;
5524
5525 case L2CAP_DISCONN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005526 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005527 break;
5528
5529 case L2CAP_ECHO_REQ:
5530 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5531 break;
5532
5533 case L2CAP_ECHO_RSP:
5534 break;
5535
5536 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005537 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005538 break;
5539
5540 case L2CAP_INFO_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005541 l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005542 break;
5543
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005544 case L2CAP_CREATE_CHAN_REQ:
5545 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5546 break;
5547
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005548 case L2CAP_MOVE_CHAN_REQ:
5549 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5550 break;
5551
5552 case L2CAP_MOVE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005553 l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005554 break;
5555
5556 case L2CAP_MOVE_CHAN_CFM:
5557 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5558 break;
5559
5560 case L2CAP_MOVE_CHAN_CFM_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005561 l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005562 break;
5563
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005564 default:
5565 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5566 err = -EINVAL;
5567 break;
5568 }
5569
5570 return err;
5571}
5572
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005573static int l2cap_le_connect_req(struct l2cap_conn *conn,
5574 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5575 u8 *data)
5576{
5577 struct l2cap_le_conn_req *req = (struct l2cap_le_conn_req *) data;
5578 struct l2cap_le_conn_rsp rsp;
5579 struct l2cap_chan *chan, *pchan;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005580 u16 dcid, scid, credits, mtu, mps;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005581 __le16 psm;
5582 u8 result;
5583
5584 if (cmd_len != sizeof(*req))
5585 return -EPROTO;
5586
5587 scid = __le16_to_cpu(req->scid);
5588 mtu = __le16_to_cpu(req->mtu);
5589 mps = __le16_to_cpu(req->mps);
5590 psm = req->psm;
5591 dcid = 0;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005592 credits = 0;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005593
5594 if (mtu < 23 || mps < 23)
5595 return -EPROTO;
5596
5597 BT_DBG("psm 0x%2.2x scid 0x%4.4x mtu %u mps %u", __le16_to_cpu(psm),
5598 scid, mtu, mps);
5599
5600 /* Check if we have socket listening on psm */
5601 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
5602 &conn->hcon->dst, LE_LINK);
5603 if (!pchan) {
5604 result = L2CAP_CR_BAD_PSM;
5605 chan = NULL;
5606 goto response;
5607 }
5608
5609 mutex_lock(&conn->chan_lock);
5610 l2cap_chan_lock(pchan);
5611
5612 if (!smp_sufficient_security(conn->hcon, pchan->sec_level)) {
5613 result = L2CAP_CR_AUTHENTICATION;
5614 chan = NULL;
5615 goto response_unlock;
5616 }
5617
5618 /* Check if we already have channel with that dcid */
5619 if (__l2cap_get_chan_by_dcid(conn, scid)) {
5620 result = L2CAP_CR_NO_MEM;
5621 chan = NULL;
5622 goto response_unlock;
5623 }
5624
5625 chan = pchan->ops->new_connection(pchan);
5626 if (!chan) {
5627 result = L2CAP_CR_NO_MEM;
5628 goto response_unlock;
5629 }
5630
5631 bacpy(&chan->src, &conn->hcon->src);
5632 bacpy(&chan->dst, &conn->hcon->dst);
5633 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
5634 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
5635 chan->psm = psm;
5636 chan->dcid = scid;
5637 chan->omtu = mtu;
5638 chan->remote_mps = mps;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005639 chan->tx_credits = __le16_to_cpu(req->credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005640
5641 __l2cap_chan_add(conn, chan);
5642 dcid = chan->scid;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005643 credits = chan->rx_credits;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005644
5645 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
5646
5647 chan->ident = cmd->ident;
5648
5649 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
5650 l2cap_state_change(chan, BT_CONNECT2);
5651 result = L2CAP_CR_PEND;
5652 chan->ops->defer(chan);
5653 } else {
5654 l2cap_chan_ready(chan);
5655 result = L2CAP_CR_SUCCESS;
5656 }
5657
5658response_unlock:
5659 l2cap_chan_unlock(pchan);
5660 mutex_unlock(&conn->chan_lock);
5661
5662 if (result == L2CAP_CR_PEND)
5663 return 0;
5664
5665response:
5666 if (chan) {
5667 rsp.mtu = cpu_to_le16(chan->imtu);
5668 rsp.mps = __constant_cpu_to_le16(L2CAP_LE_DEFAULT_MPS);
5669 } else {
5670 rsp.mtu = 0;
5671 rsp.mps = 0;
5672 }
5673
5674 rsp.dcid = cpu_to_le16(dcid);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005675 rsp.credits = cpu_to_le16(credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005676 rsp.result = cpu_to_le16(result);
5677
5678 l2cap_send_cmd(conn, cmd->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), &rsp);
5679
5680 return 0;
5681}
5682
Johan Hedbergfad5fc82013-12-05 09:45:01 +02005683static inline int l2cap_le_credits(struct l2cap_conn *conn,
5684 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5685 u8 *data)
5686{
5687 struct l2cap_le_credits *pkt;
5688 struct l2cap_chan *chan;
5689 u16 cid, credits;
5690
5691 if (cmd_len != sizeof(*pkt))
5692 return -EPROTO;
5693
5694 pkt = (struct l2cap_le_credits *) data;
5695 cid = __le16_to_cpu(pkt->cid);
5696 credits = __le16_to_cpu(pkt->credits);
5697
5698 BT_DBG("cid 0x%4.4x credits 0x%4.4x", cid, credits);
5699
5700 chan = l2cap_get_chan_by_dcid(conn, cid);
5701 if (!chan)
5702 return -EBADSLT;
5703
5704 chan->tx_credits += credits;
5705
5706 while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
5707 l2cap_do_send(chan, skb_dequeue(&chan->tx_q));
5708 chan->tx_credits--;
5709 }
5710
5711 if (chan->tx_credits)
5712 chan->ops->resume(chan);
5713
5714 l2cap_chan_unlock(chan);
5715
5716 return 0;
5717}
5718
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005719static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Johan Hedberg203e6392013-05-15 10:07:15 +03005720 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5721 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005722{
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005723 int err = 0;
5724
Johan Hedberg3af8ace2013-12-03 09:51:51 +02005725 if (!enable_lecoc) {
5726 switch (cmd->code) {
5727 case L2CAP_LE_CONN_REQ:
5728 case L2CAP_LE_CONN_RSP:
5729 case L2CAP_LE_CREDITS:
5730 case L2CAP_DISCONN_REQ:
5731 case L2CAP_DISCONN_RSP:
5732 return -EINVAL;
5733 }
5734 }
5735
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005736 switch (cmd->code) {
5737 case L2CAP_COMMAND_REJ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005738 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005739
5740 case L2CAP_CONN_PARAM_UPDATE_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005741 err = l2cap_conn_param_update_req(conn, cmd, cmd_len, data);
5742 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005743
5744 case L2CAP_CONN_PARAM_UPDATE_RSP:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005745 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005746
Johan Hedbergf1496de2013-05-13 14:15:56 +03005747 case L2CAP_LE_CONN_RSP:
5748 l2cap_le_connect_rsp(conn, cmd, cmd_len, data);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005749 break;
Johan Hedbergf1496de2013-05-13 14:15:56 +03005750
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005751 case L2CAP_LE_CONN_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005752 err = l2cap_le_connect_req(conn, cmd, cmd_len, data);
5753 break;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005754
Johan Hedbergfad5fc82013-12-05 09:45:01 +02005755 case L2CAP_LE_CREDITS:
5756 err = l2cap_le_credits(conn, cmd, cmd_len, data);
5757 break;
5758
Johan Hedberg3defe012013-05-15 10:16:06 +03005759 case L2CAP_DISCONN_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005760 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
5761 break;
Johan Hedberg3defe012013-05-15 10:16:06 +03005762
5763 case L2CAP_DISCONN_RSP:
5764 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005765 break;
Johan Hedberg3defe012013-05-15 10:16:06 +03005766
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005767 default:
5768 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005769 err = -EINVAL;
5770 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005771 }
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005772
5773 return err;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005774}
5775
Johan Hedbergc5623552013-04-29 19:35:33 +03005776static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5777 struct sk_buff *skb)
5778{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005779 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005780 struct l2cap_cmd_hdr *cmd;
5781 u16 len;
Johan Hedbergc5623552013-04-29 19:35:33 +03005782 int err;
5783
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005784 if (hcon->type != LE_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005785 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005786
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005787 if (skb->len < L2CAP_CMD_HDR_SIZE)
5788 goto drop;
Johan Hedbergc5623552013-04-29 19:35:33 +03005789
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005790 cmd = (void *) skb->data;
5791 skb_pull(skb, L2CAP_CMD_HDR_SIZE);
Johan Hedbergc5623552013-04-29 19:35:33 +03005792
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005793 len = le16_to_cpu(cmd->len);
Johan Hedbergc5623552013-04-29 19:35:33 +03005794
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005795 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, cmd->ident);
Johan Hedbergc5623552013-04-29 19:35:33 +03005796
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005797 if (len != skb->len || !cmd->ident) {
5798 BT_DBG("corrupted command");
5799 goto drop;
5800 }
Johan Hedbergc5623552013-04-29 19:35:33 +03005801
Johan Hedberg203e6392013-05-15 10:07:15 +03005802 err = l2cap_le_sig_cmd(conn, cmd, len, skb->data);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005803 if (err) {
5804 struct l2cap_cmd_rej_unk rej;
Johan Hedbergc5623552013-04-29 19:35:33 +03005805
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005806 BT_ERR("Wrong link type (%d)", err);
Johan Hedbergc5623552013-04-29 19:35:33 +03005807
Johan Hedberga5211492013-10-16 11:20:49 +03005808 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005809 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
5810 sizeof(rej), &rej);
Johan Hedbergc5623552013-04-29 19:35:33 +03005811 }
5812
Marcel Holtmann3b166292013-10-02 08:28:21 -07005813drop:
Johan Hedbergc5623552013-04-29 19:35:33 +03005814 kfree_skb(skb);
5815}
5816
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005817static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005818 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005819{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005820 struct hci_conn *hcon = conn->hcon;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005821 u8 *data = skb->data;
5822 int len = skb->len;
5823 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005824 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005825
5826 l2cap_raw_recv(conn, skb);
5827
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005828 if (hcon->type != ACL_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005829 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005830
Linus Torvalds1da177e2005-04-16 15:20:36 -07005831 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005832 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005833 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5834 data += L2CAP_CMD_HDR_SIZE;
5835 len -= L2CAP_CMD_HDR_SIZE;
5836
Al Viro88219a02007-07-29 00:17:25 -07005837 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005838
Gustavo Padovan2d792812012-10-06 10:07:01 +01005839 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5840 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005841
Al Viro88219a02007-07-29 00:17:25 -07005842 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005843 BT_DBG("corrupted command");
5844 break;
5845 }
5846
Johan Hedbergc5623552013-04-29 19:35:33 +03005847 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005848 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005849 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005850
5851 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005852
Johan Hedberga5211492013-10-16 11:20:49 +03005853 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005854 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5855 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005856 }
5857
Al Viro88219a02007-07-29 00:17:25 -07005858 data += cmd_len;
5859 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005860 }
5861
Marcel Holtmann3b166292013-10-02 08:28:21 -07005862drop:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005863 kfree_skb(skb);
5864}
5865
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005866static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005867{
5868 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005869 int hdr_size;
5870
5871 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5872 hdr_size = L2CAP_EXT_HDR_SIZE;
5873 else
5874 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005875
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005876 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005877 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005878 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5879 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5880
5881 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005882 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005883 }
5884 return 0;
5885}
5886
Mat Martineau6ea00482012-05-17 20:53:52 -07005887static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005888{
Mat Martineaue31f7632012-05-17 20:53:41 -07005889 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005890
Mat Martineaue31f7632012-05-17 20:53:41 -07005891 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005892
Mat Martineaue31f7632012-05-17 20:53:41 -07005893 memset(&control, 0, sizeof(control));
5894 control.sframe = 1;
5895 control.final = 1;
5896 control.reqseq = chan->buffer_seq;
5897 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005898
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005899 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005900 control.super = L2CAP_SUPER_RNR;
5901 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005902 }
5903
Mat Martineaue31f7632012-05-17 20:53:41 -07005904 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5905 chan->unacked_frames > 0)
5906 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005907
Mat Martineaue31f7632012-05-17 20:53:41 -07005908 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005909 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005910
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005911 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005912 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5913 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5914 * send it now.
5915 */
5916 control.super = L2CAP_SUPER_RR;
5917 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005918 }
5919}
5920
Gustavo Padovan2d792812012-10-06 10:07:01 +01005921static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5922 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005923{
Mat Martineau84084a32011-07-22 14:54:00 -07005924 /* skb->len reflects data in skb as well as all fragments
5925 * skb->data_len reflects only data in fragments
5926 */
5927 if (!skb_has_frag_list(skb))
5928 skb_shinfo(skb)->frag_list = new_frag;
5929
5930 new_frag->next = NULL;
5931
5932 (*last_frag)->next = new_frag;
5933 *last_frag = new_frag;
5934
5935 skb->len += new_frag->len;
5936 skb->data_len += new_frag->len;
5937 skb->truesize += new_frag->truesize;
5938}
5939
Mat Martineau4b51dae92012-05-17 20:53:37 -07005940static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5941 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005942{
5943 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005944
Mat Martineau4b51dae92012-05-17 20:53:37 -07005945 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005946 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005947 if (chan->sdu)
5948 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005949
Gustavo Padovan80b98022012-05-27 22:27:51 -03005950 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005951 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005952
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005953 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005954 if (chan->sdu)
5955 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005956
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005957 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005958 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005959
Mat Martineau84084a32011-07-22 14:54:00 -07005960 if (chan->sdu_len > chan->imtu) {
5961 err = -EMSGSIZE;
5962 break;
5963 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005964
Mat Martineau84084a32011-07-22 14:54:00 -07005965 if (skb->len >= chan->sdu_len)
5966 break;
5967
5968 chan->sdu = skb;
5969 chan->sdu_last_frag = skb;
5970
5971 skb = NULL;
5972 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005973 break;
5974
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005975 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005976 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005977 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005978
Mat Martineau84084a32011-07-22 14:54:00 -07005979 append_skb_frag(chan->sdu, skb,
5980 &chan->sdu_last_frag);
5981 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005982
Mat Martineau84084a32011-07-22 14:54:00 -07005983 if (chan->sdu->len >= chan->sdu_len)
5984 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005985
Mat Martineau84084a32011-07-22 14:54:00 -07005986 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005987 break;
5988
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005989 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005990 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005991 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005992
Mat Martineau84084a32011-07-22 14:54:00 -07005993 append_skb_frag(chan->sdu, skb,
5994 &chan->sdu_last_frag);
5995 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005996
Mat Martineau84084a32011-07-22 14:54:00 -07005997 if (chan->sdu->len != chan->sdu_len)
5998 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005999
Gustavo Padovan80b98022012-05-27 22:27:51 -03006000 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03006001
Mat Martineau84084a32011-07-22 14:54:00 -07006002 if (!err) {
6003 /* Reassembly complete */
6004 chan->sdu = NULL;
6005 chan->sdu_last_frag = NULL;
6006 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03006007 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006008 break;
6009 }
6010
Mat Martineau84084a32011-07-22 14:54:00 -07006011 if (err) {
6012 kfree_skb(skb);
6013 kfree_skb(chan->sdu);
6014 chan->sdu = NULL;
6015 chan->sdu_last_frag = NULL;
6016 chan->sdu_len = 0;
6017 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006018
Mat Martineau84084a32011-07-22 14:54:00 -07006019 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006020}
6021
Mat Martineau32b32732012-10-23 15:24:11 -07006022static int l2cap_resegment(struct l2cap_chan *chan)
6023{
6024 /* Placeholder */
6025 return 0;
6026}
6027
Mat Martineaue3281402011-07-07 09:39:02 -07006028void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132eb2010-06-21 19:39:50 -03006029{
Mat Martineau61aa4f52012-05-17 20:53:40 -07006030 u8 event;
6031
6032 if (chan->mode != L2CAP_MODE_ERTM)
6033 return;
6034
6035 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03006036 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03006037}
6038
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006039static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
6040{
Mat Martineau63838722012-05-17 20:53:45 -07006041 int err = 0;
6042 /* Pass sequential frames to l2cap_reassemble_sdu()
6043 * until a gap is encountered.
6044 */
6045
6046 BT_DBG("chan %p", chan);
6047
6048 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6049 struct sk_buff *skb;
6050 BT_DBG("Searching for skb with txseq %d (queue len %d)",
6051 chan->buffer_seq, skb_queue_len(&chan->srej_q));
6052
6053 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
6054
6055 if (!skb)
6056 break;
6057
6058 skb_unlink(skb, &chan->srej_q);
6059 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6060 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
6061 if (err)
6062 break;
6063 }
6064
6065 if (skb_queue_empty(&chan->srej_q)) {
6066 chan->rx_state = L2CAP_RX_STATE_RECV;
6067 l2cap_send_ack(chan);
6068 }
6069
6070 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006071}
6072
6073static void l2cap_handle_srej(struct l2cap_chan *chan,
6074 struct l2cap_ctrl *control)
6075{
Mat Martineauf80842a2012-05-17 20:53:46 -07006076 struct sk_buff *skb;
6077
6078 BT_DBG("chan %p, control %p", chan, control);
6079
6080 if (control->reqseq == chan->next_tx_seq) {
6081 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006082 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07006083 return;
6084 }
6085
6086 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
6087
6088 if (skb == NULL) {
6089 BT_DBG("Seq %d not available for retransmission",
6090 control->reqseq);
6091 return;
6092 }
6093
6094 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
6095 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006096 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07006097 return;
6098 }
6099
6100 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6101
6102 if (control->poll) {
6103 l2cap_pass_to_tx(chan, control);
6104
6105 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6106 l2cap_retransmit(chan, control);
6107 l2cap_ertm_send(chan);
6108
6109 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
6110 set_bit(CONN_SREJ_ACT, &chan->conn_state);
6111 chan->srej_save_reqseq = control->reqseq;
6112 }
6113 } else {
6114 l2cap_pass_to_tx_fbit(chan, control);
6115
6116 if (control->final) {
6117 if (chan->srej_save_reqseq != control->reqseq ||
6118 !test_and_clear_bit(CONN_SREJ_ACT,
6119 &chan->conn_state))
6120 l2cap_retransmit(chan, control);
6121 } else {
6122 l2cap_retransmit(chan, control);
6123 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
6124 set_bit(CONN_SREJ_ACT, &chan->conn_state);
6125 chan->srej_save_reqseq = control->reqseq;
6126 }
6127 }
6128 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006129}
6130
6131static void l2cap_handle_rej(struct l2cap_chan *chan,
6132 struct l2cap_ctrl *control)
6133{
Mat Martineaufcd289d2012-05-17 20:53:47 -07006134 struct sk_buff *skb;
6135
6136 BT_DBG("chan %p, control %p", chan, control);
6137
6138 if (control->reqseq == chan->next_tx_seq) {
6139 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006140 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07006141 return;
6142 }
6143
6144 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
6145
6146 if (chan->max_tx && skb &&
6147 bt_cb(skb)->control.retries >= chan->max_tx) {
6148 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006149 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07006150 return;
6151 }
6152
6153 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6154
6155 l2cap_pass_to_tx(chan, control);
6156
6157 if (control->final) {
6158 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
6159 l2cap_retransmit_all(chan, control);
6160 } else {
6161 l2cap_retransmit_all(chan, control);
6162 l2cap_ertm_send(chan);
6163 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
6164 set_bit(CONN_REJ_ACT, &chan->conn_state);
6165 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006166}
6167
Mat Martineau4b51dae92012-05-17 20:53:37 -07006168static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
6169{
6170 BT_DBG("chan %p, txseq %d", chan, txseq);
6171
6172 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
6173 chan->expected_tx_seq);
6174
6175 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
6176 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01006177 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07006178 /* See notes below regarding "double poll" and
6179 * invalid packets.
6180 */
6181 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
6182 BT_DBG("Invalid/Ignore - after SREJ");
6183 return L2CAP_TXSEQ_INVALID_IGNORE;
6184 } else {
6185 BT_DBG("Invalid - in window after SREJ sent");
6186 return L2CAP_TXSEQ_INVALID;
6187 }
6188 }
6189
6190 if (chan->srej_list.head == txseq) {
6191 BT_DBG("Expected SREJ");
6192 return L2CAP_TXSEQ_EXPECTED_SREJ;
6193 }
6194
6195 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
6196 BT_DBG("Duplicate SREJ - txseq already stored");
6197 return L2CAP_TXSEQ_DUPLICATE_SREJ;
6198 }
6199
6200 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
6201 BT_DBG("Unexpected SREJ - not requested");
6202 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
6203 }
6204 }
6205
6206 if (chan->expected_tx_seq == txseq) {
6207 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
6208 chan->tx_win) {
6209 BT_DBG("Invalid - txseq outside tx window");
6210 return L2CAP_TXSEQ_INVALID;
6211 } else {
6212 BT_DBG("Expected");
6213 return L2CAP_TXSEQ_EXPECTED;
6214 }
6215 }
6216
6217 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01006218 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07006219 BT_DBG("Duplicate - expected_tx_seq later than txseq");
6220 return L2CAP_TXSEQ_DUPLICATE;
6221 }
6222
6223 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
6224 /* A source of invalid packets is a "double poll" condition,
6225 * where delays cause us to send multiple poll packets. If
6226 * the remote stack receives and processes both polls,
6227 * sequence numbers can wrap around in such a way that a
6228 * resent frame has a sequence number that looks like new data
6229 * with a sequence gap. This would trigger an erroneous SREJ
6230 * request.
6231 *
6232 * Fortunately, this is impossible with a tx window that's
6233 * less than half of the maximum sequence number, which allows
6234 * invalid frames to be safely ignored.
6235 *
6236 * With tx window sizes greater than half of the tx window
6237 * maximum, the frame is invalid and cannot be ignored. This
6238 * causes a disconnect.
6239 */
6240
6241 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
6242 BT_DBG("Invalid/Ignore - txseq outside tx window");
6243 return L2CAP_TXSEQ_INVALID_IGNORE;
6244 } else {
6245 BT_DBG("Invalid - txseq outside tx window");
6246 return L2CAP_TXSEQ_INVALID;
6247 }
6248 } else {
6249 BT_DBG("Unexpected - txseq indicates missing frames");
6250 return L2CAP_TXSEQ_UNEXPECTED;
6251 }
6252}
6253
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006254static int l2cap_rx_state_recv(struct l2cap_chan *chan,
6255 struct l2cap_ctrl *control,
6256 struct sk_buff *skb, u8 event)
6257{
6258 int err = 0;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006259 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006260
6261 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6262 event);
6263
6264 switch (event) {
6265 case L2CAP_EV_RECV_IFRAME:
6266 switch (l2cap_classify_txseq(chan, control->txseq)) {
6267 case L2CAP_TXSEQ_EXPECTED:
6268 l2cap_pass_to_tx(chan, control);
6269
6270 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6271 BT_DBG("Busy, discarding expected seq %d",
6272 control->txseq);
6273 break;
6274 }
6275
6276 chan->expected_tx_seq = __next_seq(chan,
6277 control->txseq);
6278
6279 chan->buffer_seq = chan->expected_tx_seq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006280 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006281
6282 err = l2cap_reassemble_sdu(chan, skb, control);
6283 if (err)
6284 break;
6285
6286 if (control->final) {
6287 if (!test_and_clear_bit(CONN_REJ_ACT,
6288 &chan->conn_state)) {
6289 control->final = 0;
6290 l2cap_retransmit_all(chan, control);
6291 l2cap_ertm_send(chan);
6292 }
6293 }
6294
6295 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
6296 l2cap_send_ack(chan);
6297 break;
6298 case L2CAP_TXSEQ_UNEXPECTED:
6299 l2cap_pass_to_tx(chan, control);
6300
6301 /* Can't issue SREJ frames in the local busy state.
6302 * Drop this frame, it will be seen as missing
6303 * when local busy is exited.
6304 */
6305 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6306 BT_DBG("Busy, discarding unexpected seq %d",
6307 control->txseq);
6308 break;
6309 }
6310
6311 /* There was a gap in the sequence, so an SREJ
6312 * must be sent for each missing frame. The
6313 * current frame is stored for later use.
6314 */
6315 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006316 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006317 BT_DBG("Queued %p (queue len %d)", skb,
6318 skb_queue_len(&chan->srej_q));
6319
6320 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
6321 l2cap_seq_list_clear(&chan->srej_list);
6322 l2cap_send_srej(chan, control->txseq);
6323
6324 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
6325 break;
6326 case L2CAP_TXSEQ_DUPLICATE:
6327 l2cap_pass_to_tx(chan, control);
6328 break;
6329 case L2CAP_TXSEQ_INVALID_IGNORE:
6330 break;
6331 case L2CAP_TXSEQ_INVALID:
6332 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006333 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006334 break;
6335 }
6336 break;
6337 case L2CAP_EV_RECV_RR:
6338 l2cap_pass_to_tx(chan, control);
6339 if (control->final) {
6340 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6341
Mat Martineaue6a3ee62012-10-23 15:24:22 -07006342 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
6343 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006344 control->final = 0;
6345 l2cap_retransmit_all(chan, control);
6346 }
6347
6348 l2cap_ertm_send(chan);
6349 } else if (control->poll) {
6350 l2cap_send_i_or_rr_or_rnr(chan);
6351 } else {
6352 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6353 &chan->conn_state) &&
6354 chan->unacked_frames)
6355 __set_retrans_timer(chan);
6356
6357 l2cap_ertm_send(chan);
6358 }
6359 break;
6360 case L2CAP_EV_RECV_RNR:
6361 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6362 l2cap_pass_to_tx(chan, control);
6363 if (control && control->poll) {
6364 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6365 l2cap_send_rr_or_rnr(chan, 0);
6366 }
6367 __clear_retrans_timer(chan);
6368 l2cap_seq_list_clear(&chan->retrans_list);
6369 break;
6370 case L2CAP_EV_RECV_REJ:
6371 l2cap_handle_rej(chan, control);
6372 break;
6373 case L2CAP_EV_RECV_SREJ:
6374 l2cap_handle_srej(chan, control);
6375 break;
6376 default:
6377 break;
6378 }
6379
6380 if (skb && !skb_in_use) {
6381 BT_DBG("Freeing %p", skb);
6382 kfree_skb(skb);
6383 }
6384
6385 return err;
6386}
6387
6388static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
6389 struct l2cap_ctrl *control,
6390 struct sk_buff *skb, u8 event)
6391{
6392 int err = 0;
6393 u16 txseq = control->txseq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006394 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006395
6396 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6397 event);
6398
6399 switch (event) {
6400 case L2CAP_EV_RECV_IFRAME:
6401 switch (l2cap_classify_txseq(chan, txseq)) {
6402 case L2CAP_TXSEQ_EXPECTED:
6403 /* Keep frame for reassembly later */
6404 l2cap_pass_to_tx(chan, control);
6405 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006406 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006407 BT_DBG("Queued %p (queue len %d)", skb,
6408 skb_queue_len(&chan->srej_q));
6409
6410 chan->expected_tx_seq = __next_seq(chan, txseq);
6411 break;
6412 case L2CAP_TXSEQ_EXPECTED_SREJ:
6413 l2cap_seq_list_pop(&chan->srej_list);
6414
6415 l2cap_pass_to_tx(chan, control);
6416 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006417 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006418 BT_DBG("Queued %p (queue len %d)", skb,
6419 skb_queue_len(&chan->srej_q));
6420
6421 err = l2cap_rx_queued_iframes(chan);
6422 if (err)
6423 break;
6424
6425 break;
6426 case L2CAP_TXSEQ_UNEXPECTED:
6427 /* Got a frame that can't be reassembled yet.
6428 * Save it for later, and send SREJs to cover
6429 * the missing frames.
6430 */
6431 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006432 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006433 BT_DBG("Queued %p (queue len %d)", skb,
6434 skb_queue_len(&chan->srej_q));
6435
6436 l2cap_pass_to_tx(chan, control);
6437 l2cap_send_srej(chan, control->txseq);
6438 break;
6439 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
6440 /* This frame was requested with an SREJ, but
6441 * some expected retransmitted frames are
6442 * missing. Request retransmission of missing
6443 * SREJ'd frames.
6444 */
6445 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006446 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006447 BT_DBG("Queued %p (queue len %d)", skb,
6448 skb_queue_len(&chan->srej_q));
6449
6450 l2cap_pass_to_tx(chan, control);
6451 l2cap_send_srej_list(chan, control->txseq);
6452 break;
6453 case L2CAP_TXSEQ_DUPLICATE_SREJ:
6454 /* We've already queued this frame. Drop this copy. */
6455 l2cap_pass_to_tx(chan, control);
6456 break;
6457 case L2CAP_TXSEQ_DUPLICATE:
6458 /* Expecting a later sequence number, so this frame
6459 * was already received. Ignore it completely.
6460 */
6461 break;
6462 case L2CAP_TXSEQ_INVALID_IGNORE:
6463 break;
6464 case L2CAP_TXSEQ_INVALID:
6465 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006466 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006467 break;
6468 }
6469 break;
6470 case L2CAP_EV_RECV_RR:
6471 l2cap_pass_to_tx(chan, control);
6472 if (control->final) {
6473 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6474
6475 if (!test_and_clear_bit(CONN_REJ_ACT,
6476 &chan->conn_state)) {
6477 control->final = 0;
6478 l2cap_retransmit_all(chan, control);
6479 }
6480
6481 l2cap_ertm_send(chan);
6482 } else if (control->poll) {
6483 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6484 &chan->conn_state) &&
6485 chan->unacked_frames) {
6486 __set_retrans_timer(chan);
6487 }
6488
6489 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6490 l2cap_send_srej_tail(chan);
6491 } else {
6492 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6493 &chan->conn_state) &&
6494 chan->unacked_frames)
6495 __set_retrans_timer(chan);
6496
6497 l2cap_send_ack(chan);
6498 }
6499 break;
6500 case L2CAP_EV_RECV_RNR:
6501 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6502 l2cap_pass_to_tx(chan, control);
6503 if (control->poll) {
6504 l2cap_send_srej_tail(chan);
6505 } else {
6506 struct l2cap_ctrl rr_control;
6507 memset(&rr_control, 0, sizeof(rr_control));
6508 rr_control.sframe = 1;
6509 rr_control.super = L2CAP_SUPER_RR;
6510 rr_control.reqseq = chan->buffer_seq;
6511 l2cap_send_sframe(chan, &rr_control);
6512 }
6513
6514 break;
6515 case L2CAP_EV_RECV_REJ:
6516 l2cap_handle_rej(chan, control);
6517 break;
6518 case L2CAP_EV_RECV_SREJ:
6519 l2cap_handle_srej(chan, control);
6520 break;
6521 }
6522
6523 if (skb && !skb_in_use) {
6524 BT_DBG("Freeing %p", skb);
6525 kfree_skb(skb);
6526 }
6527
6528 return err;
6529}
6530
Mat Martineau32b32732012-10-23 15:24:11 -07006531static int l2cap_finish_move(struct l2cap_chan *chan)
6532{
6533 BT_DBG("chan %p", chan);
6534
6535 chan->rx_state = L2CAP_RX_STATE_RECV;
6536
6537 if (chan->hs_hcon)
6538 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6539 else
6540 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6541
6542 return l2cap_resegment(chan);
6543}
6544
6545static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6546 struct l2cap_ctrl *control,
6547 struct sk_buff *skb, u8 event)
6548{
6549 int err;
6550
6551 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6552 event);
6553
6554 if (!control->poll)
6555 return -EPROTO;
6556
6557 l2cap_process_reqseq(chan, control->reqseq);
6558
6559 if (!skb_queue_empty(&chan->tx_q))
6560 chan->tx_send_head = skb_peek(&chan->tx_q);
6561 else
6562 chan->tx_send_head = NULL;
6563
6564 /* Rewind next_tx_seq to the point expected
6565 * by the receiver.
6566 */
6567 chan->next_tx_seq = control->reqseq;
6568 chan->unacked_frames = 0;
6569
6570 err = l2cap_finish_move(chan);
6571 if (err)
6572 return err;
6573
6574 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6575 l2cap_send_i_or_rr_or_rnr(chan);
6576
6577 if (event == L2CAP_EV_RECV_IFRAME)
6578 return -EPROTO;
6579
6580 return l2cap_rx_state_recv(chan, control, NULL, event);
6581}
6582
6583static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6584 struct l2cap_ctrl *control,
6585 struct sk_buff *skb, u8 event)
6586{
6587 int err;
6588
6589 if (!control->final)
6590 return -EPROTO;
6591
6592 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6593
6594 chan->rx_state = L2CAP_RX_STATE_RECV;
6595 l2cap_process_reqseq(chan, control->reqseq);
6596
6597 if (!skb_queue_empty(&chan->tx_q))
6598 chan->tx_send_head = skb_peek(&chan->tx_q);
6599 else
6600 chan->tx_send_head = NULL;
6601
6602 /* Rewind next_tx_seq to the point expected
6603 * by the receiver.
6604 */
6605 chan->next_tx_seq = control->reqseq;
6606 chan->unacked_frames = 0;
6607
6608 if (chan->hs_hcon)
6609 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6610 else
6611 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6612
6613 err = l2cap_resegment(chan);
6614
6615 if (!err)
6616 err = l2cap_rx_state_recv(chan, control, skb, event);
6617
6618 return err;
6619}
6620
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006621static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6622{
6623 /* Make sure reqseq is for a packet that has been sent but not acked */
6624 u16 unacked;
6625
6626 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6627 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6628}
6629
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006630static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6631 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006632{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006633 int err = 0;
6634
6635 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6636 control, skb, event, chan->rx_state);
6637
6638 if (__valid_reqseq(chan, control->reqseq)) {
6639 switch (chan->rx_state) {
6640 case L2CAP_RX_STATE_RECV:
6641 err = l2cap_rx_state_recv(chan, control, skb, event);
6642 break;
6643 case L2CAP_RX_STATE_SREJ_SENT:
6644 err = l2cap_rx_state_srej_sent(chan, control, skb,
6645 event);
6646 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006647 case L2CAP_RX_STATE_WAIT_P:
6648 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6649 break;
6650 case L2CAP_RX_STATE_WAIT_F:
6651 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6652 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006653 default:
6654 /* shut it down */
6655 break;
6656 }
6657 } else {
6658 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6659 control->reqseq, chan->next_tx_seq,
6660 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006661 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006662 }
6663
6664 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006665}
6666
6667static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6668 struct sk_buff *skb)
6669{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006670 int err = 0;
6671
6672 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6673 chan->rx_state);
6674
6675 if (l2cap_classify_txseq(chan, control->txseq) ==
6676 L2CAP_TXSEQ_EXPECTED) {
6677 l2cap_pass_to_tx(chan, control);
6678
6679 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6680 __next_seq(chan, chan->buffer_seq));
6681
6682 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6683
6684 l2cap_reassemble_sdu(chan, skb, control);
6685 } else {
6686 if (chan->sdu) {
6687 kfree_skb(chan->sdu);
6688 chan->sdu = NULL;
6689 }
6690 chan->sdu_last_frag = NULL;
6691 chan->sdu_len = 0;
6692
6693 if (skb) {
6694 BT_DBG("Freeing %p", skb);
6695 kfree_skb(skb);
6696 }
6697 }
6698
6699 chan->last_acked_seq = control->txseq;
6700 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6701
6702 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006703}
6704
6705static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6706{
6707 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6708 u16 len;
6709 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006710
Mat Martineaub76bbd62012-04-11 10:48:43 -07006711 __unpack_control(chan, skb);
6712
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006713 len = skb->len;
6714
6715 /*
6716 * We can just drop the corrupted I-frame here.
6717 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006718 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006719 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006720 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006721 goto drop;
6722
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006723 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006724 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006725
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006726 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006727 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006728
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006729 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006730 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006731 goto drop;
6732 }
6733
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006734 if (!control->sframe) {
6735 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006736
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006737 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6738 control->sar, control->reqseq, control->final,
6739 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006740
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006741 /* Validate F-bit - F=0 always valid, F=1 only
6742 * valid in TX WAIT_F
6743 */
6744 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006745 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006746
6747 if (chan->mode != L2CAP_MODE_STREAMING) {
6748 event = L2CAP_EV_RECV_IFRAME;
6749 err = l2cap_rx(chan, control, skb, event);
6750 } else {
6751 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006752 }
6753
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006754 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006755 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006756 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006757 const u8 rx_func_to_event[4] = {
6758 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6759 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6760 };
6761
6762 /* Only I-frames are expected in streaming mode */
6763 if (chan->mode == L2CAP_MODE_STREAMING)
6764 goto drop;
6765
6766 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6767 control->reqseq, control->final, control->poll,
6768 control->super);
6769
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006770 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006771 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006772 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006773 goto drop;
6774 }
6775
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006776 /* Validate F and P bits */
6777 if (control->final && (control->poll ||
6778 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6779 goto drop;
6780
6781 event = rx_func_to_event[control->super];
6782 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006783 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006784 }
6785
6786 return 0;
6787
6788drop:
6789 kfree_skb(skb);
6790 return 0;
6791}
6792
Johan Hedbergb1c325c2013-12-05 09:43:34 +02006793static void l2cap_chan_le_send_credits(struct l2cap_chan *chan)
6794{
6795 struct l2cap_conn *conn = chan->conn;
6796 struct l2cap_le_credits pkt;
6797 u16 return_credits;
6798
6799 /* We return more credits to the sender only after the amount of
6800 * credits falls below half of the initial amount.
6801 */
6802 if (chan->rx_credits >= (L2CAP_LE_MAX_CREDITS + 1) / 2)
6803 return;
6804
6805 return_credits = L2CAP_LE_MAX_CREDITS - chan->rx_credits;
6806
6807 BT_DBG("chan %p returning %u credits to sender", chan, return_credits);
6808
6809 chan->rx_credits += return_credits;
6810
6811 pkt.cid = cpu_to_le16(chan->scid);
6812 pkt.credits = cpu_to_le16(return_credits);
6813
6814 chan->ident = l2cap_get_ident(conn);
6815
6816 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CREDITS, sizeof(pkt), &pkt);
6817}
6818
Johan Hedbergfad5fc82013-12-05 09:45:01 +02006819static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6820{
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006821 int err;
Johan Hedbergfad5fc82013-12-05 09:45:01 +02006822
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006823 if (!chan->rx_credits) {
6824 BT_ERR("No credits to receive LE L2CAP data");
Johan Hedbergfad5fc82013-12-05 09:45:01 +02006825 return -ENOBUFS;
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006826 }
6827
6828 if (chan->imtu < skb->len) {
6829 BT_ERR("Too big LE L2CAP PDU");
6830 return -ENOBUFS;
6831 }
Johan Hedbergfad5fc82013-12-05 09:45:01 +02006832
6833 chan->rx_credits--;
6834 BT_DBG("rx_credits %u -> %u", chan->rx_credits + 1, chan->rx_credits);
6835
6836 l2cap_chan_le_send_credits(chan);
6837
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006838 err = 0;
6839
6840 if (!chan->sdu) {
6841 u16 sdu_len;
6842
6843 sdu_len = get_unaligned_le16(skb->data);
6844 skb_pull(skb, L2CAP_SDULEN_SIZE);
6845
6846 BT_DBG("Start of new SDU. sdu_len %u skb->len %u imtu %u",
6847 sdu_len, skb->len, chan->imtu);
6848
6849 if (sdu_len > chan->imtu) {
6850 BT_ERR("Too big LE L2CAP SDU length received");
6851 err = -EMSGSIZE;
6852 goto failed;
6853 }
6854
6855 if (skb->len > sdu_len) {
6856 BT_ERR("Too much LE L2CAP data received");
6857 err = -EINVAL;
6858 goto failed;
6859 }
6860
6861 if (skb->len == sdu_len)
6862 return chan->ops->recv(chan, skb);
6863
6864 chan->sdu = skb;
6865 chan->sdu_len = sdu_len;
6866 chan->sdu_last_frag = skb;
6867
6868 return 0;
6869 }
6870
6871 BT_DBG("SDU fragment. chan->sdu->len %u skb->len %u chan->sdu_len %u",
6872 chan->sdu->len, skb->len, chan->sdu_len);
6873
6874 if (chan->sdu->len + skb->len > chan->sdu_len) {
6875 BT_ERR("Too much LE L2CAP data received");
6876 err = -EINVAL;
6877 goto failed;
6878 }
6879
6880 append_skb_frag(chan->sdu, skb, &chan->sdu_last_frag);
6881 skb = NULL;
6882
6883 if (chan->sdu->len == chan->sdu_len) {
6884 err = chan->ops->recv(chan, chan->sdu);
6885 if (!err) {
6886 chan->sdu = NULL;
6887 chan->sdu_last_frag = NULL;
6888 chan->sdu_len = 0;
6889 }
6890 }
6891
6892failed:
6893 if (err) {
6894 kfree_skb(skb);
6895 kfree_skb(chan->sdu);
6896 chan->sdu = NULL;
6897 chan->sdu_last_frag = NULL;
6898 chan->sdu_len = 0;
6899 }
6900
6901 /* We can't return an error here since we took care of the skb
6902 * freeing internally. An error return would cause the caller to
6903 * do a double-free of the skb.
6904 */
6905 return 0;
Johan Hedbergfad5fc82013-12-05 09:45:01 +02006906}
6907
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006908static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6909 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006910{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006911 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006912
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006913 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006914 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006915 if (cid == L2CAP_CID_A2MP) {
6916 chan = a2mp_channel_create(conn, skb);
6917 if (!chan) {
6918 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006919 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006920 }
6921
6922 l2cap_chan_lock(chan);
6923 } else {
6924 BT_DBG("unknown cid 0x%4.4x", cid);
6925 /* Drop packet and return */
6926 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006927 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006928 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006929 }
6930
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006931 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006932
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006933 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006934 goto drop;
6935
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006936 switch (chan->mode) {
Johan Hedberg38319712013-05-17 12:49:23 +03006937 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedbergfad5fc82013-12-05 09:45:01 +02006938 if (l2cap_le_data_rcv(chan, skb) < 0)
6939 goto drop;
6940
6941 goto done;
6942
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006943 case L2CAP_MODE_BASIC:
6944 /* If socket recv buffers overflows we drop data here
6945 * which is *bad* because L2CAP has to be reliable.
6946 * But we don't have any other choice. L2CAP doesn't
6947 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006948
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006949 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006950 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006951
Gustavo Padovan80b98022012-05-27 22:27:51 -03006952 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006953 goto done;
6954 break;
6955
6956 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006957 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006958 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006959 goto done;
6960
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006961 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006962 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006963 break;
6964 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006965
6966drop:
6967 kfree_skb(skb);
6968
6969done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006970 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006971}
6972
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006973static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6974 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006975{
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006976 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006977 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006978
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006979 if (hcon->type != ACL_LINK)
6980 goto drop;
6981
Johan Hedbergbf20fd42013-05-14 13:23:13 +03006982 chan = l2cap_global_chan_by_psm(0, psm, &hcon->src, &hcon->dst,
6983 ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006984 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006985 goto drop;
6986
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006987 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006988
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006989 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006990 goto drop;
6991
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006992 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006993 goto drop;
6994
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006995 /* Store remote BD_ADDR and PSM for msg_name */
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006996 bacpy(&bt_cb(skb)->bdaddr, &hcon->dst);
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006997 bt_cb(skb)->psm = psm;
6998
Gustavo Padovan80b98022012-05-27 22:27:51 -03006999 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03007000 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007001
7002drop:
7003 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007004}
7005
Marcel Holtmann72f78352013-04-23 00:59:00 -07007006static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03007007 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007008{
Marcel Holtmannb99707d2013-10-03 02:54:11 -07007009 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007010 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007011
Marcel Holtmannb99707d2013-10-03 02:54:11 -07007012 if (hcon->type != LE_LINK)
7013 goto drop;
7014
Johan Hedbergaf1c0132013-04-29 19:35:42 +03007015 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann06ae3312013-10-18 03:43:00 -07007016 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007017 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007018 goto drop;
7019
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02007020 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007021
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07007022 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, hcon->dst_type))
7023 goto drop;
7024
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03007025 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007026 goto drop;
7027
Gustavo Padovan80b98022012-05-27 22:27:51 -03007028 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03007029 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007030
7031drop:
7032 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007033}
7034
Linus Torvalds1da177e2005-04-16 15:20:36 -07007035static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
7036{
7037 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07007038 u16 cid, len;
7039 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007040
7041 skb_pull(skb, L2CAP_HDR_SIZE);
7042 cid = __le16_to_cpu(lh->cid);
7043 len = __le16_to_cpu(lh->len);
7044
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03007045 if (len != skb->len) {
7046 kfree_skb(skb);
7047 return;
7048 }
7049
Linus Torvalds1da177e2005-04-16 15:20:36 -07007050 BT_DBG("len %d, cid 0x%4.4x", len, cid);
7051
7052 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03007053 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007054 l2cap_sig_channel(conn, skb);
7055 break;
7056
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03007057 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02007058 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03007059 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007060 l2cap_conless_channel(conn, psm, skb);
7061 break;
7062
Johan Hedberg073d1cf2013-04-29 19:35:35 +03007063 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07007064 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007065 break;
7066
Marcel Holtmanna2877622013-10-02 23:46:54 -07007067 case L2CAP_CID_LE_SIGNALING:
7068 l2cap_le_sig_channel(conn, skb);
7069 break;
7070
Anderson Brigliab501d6a2011-06-07 18:46:31 -03007071 case L2CAP_CID_SMP:
7072 if (smp_sig_channel(conn, skb))
7073 l2cap_conn_del(conn->hcon, EACCES);
7074 break;
7075
Linus Torvalds1da177e2005-04-16 15:20:36 -07007076 default:
7077 l2cap_data_channel(conn, cid, skb);
7078 break;
7079 }
7080}
7081
7082/* ---- L2CAP interface with lower layer (HCI) ---- */
7083
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007084int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007085{
7086 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007087 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007088
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03007089 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007090
7091 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007092 read_lock(&chan_list_lock);
7093 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03007094 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007095 continue;
7096
Marcel Holtmann7eafc592013-10-13 08:12:47 -07007097 if (!bacmp(&c->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007098 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03007099 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007100 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007101 exact++;
Marcel Holtmann7eafc592013-10-13 08:12:47 -07007102 } else if (!bacmp(&c->src, BDADDR_ANY)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007103 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03007104 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007105 lm2 |= HCI_LM_MASTER;
7106 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007107 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007108 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007109
7110 return exact ? lm1 : lm2;
7111}
7112
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03007113void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007114{
Marcel Holtmann01394182006-07-03 10:02:46 +02007115 struct l2cap_conn *conn;
7116
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03007117 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007118
Linus Torvalds1da177e2005-04-16 15:20:36 -07007119 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03007120 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007121 if (conn)
7122 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02007123 } else {
Joe Perchese1750722011-06-29 18:18:29 -07007124 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02007125 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007126}
7127
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007128int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01007129{
7130 struct l2cap_conn *conn = hcon->l2cap_data;
7131
7132 BT_DBG("hcon %p", hcon);
7133
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007134 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02007135 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01007136 return conn->disc_reason;
7137}
7138
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03007139void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007140{
7141 BT_DBG("hcon %p reason %d", hcon, reason);
7142
Joe Perchese1750722011-06-29 18:18:29 -07007143 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007144}
7145
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007146static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007147{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03007148 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01007149 return;
7150
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007151 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007152 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007153 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007154 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03007155 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007156 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007157 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03007158 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007159 }
7160}
7161
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007162int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007163{
Marcel Holtmann40be4922008-07-14 20:13:50 +02007164 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03007165 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007166
Marcel Holtmann01394182006-07-03 10:02:46 +02007167 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007168 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02007169
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03007170 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007171
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03007172 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05307173 if (!status && encrypt)
7174 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02007175 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03007176 }
7177
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007178 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007179
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007180 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007181 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007182
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03007183 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
7184 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007185
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03007186 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
7187 l2cap_chan_unlock(chan);
7188 continue;
7189 }
7190
Johan Hedberg073d1cf2013-04-29 19:35:35 +03007191 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007192 if (!status && encrypt) {
7193 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02007194 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007195 }
7196
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007197 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007198 continue;
7199 }
7200
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02007201 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007202 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01007203 continue;
7204 }
7205
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03007206 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01007207 chan->state == BT_CONFIG)) {
Marcel Holtmannd97c8992013-10-14 02:53:54 -07007208 chan->ops->resume(chan);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007209 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007210 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02007211 continue;
7212 }
7213
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03007214 if (chan->state == BT_CONNECT) {
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02007215 if (!status)
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03007216 l2cap_start_connection(chan);
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02007217 else
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007218 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03007219 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007220 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007221 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007222
7223 if (!status) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07007224 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007225 res = L2CAP_CR_PEND;
7226 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08007227 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007228 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02007229 l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007230 res = L2CAP_CR_SUCCESS;
7231 stat = L2CAP_CS_NO_INFO;
7232 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007233 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02007234 l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007235 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007236 res = L2CAP_CR_SEC_BLOCK;
7237 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007238 }
7239
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03007240 rsp.scid = cpu_to_le16(chan->dcid);
7241 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007242 rsp.result = cpu_to_le16(res);
7243 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03007244 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01007245 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07007246
7247 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
7248 res == L2CAP_CR_SUCCESS) {
7249 char buf[128];
7250 set_bit(CONF_REQ_SENT, &chan->conf_state);
7251 l2cap_send_cmd(conn, l2cap_get_ident(conn),
7252 L2CAP_CONF_REQ,
7253 l2cap_build_conf_req(chan, buf),
7254 buf);
7255 chan->num_conf_req++;
7256 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007257 }
7258
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007259 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007260 }
7261
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007262 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007263
Linus Torvalds1da177e2005-04-16 15:20:36 -07007264 return 0;
7265}
7266
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007267int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007268{
7269 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007270 struct l2cap_hdr *hdr;
7271 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007272
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03007273 /* For AMP controller do not create l2cap conn */
7274 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
7275 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007276
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02007277 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03007278 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02007279
7280 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007281 goto drop;
7282
7283 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
7284
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007285 switch (flags) {
7286 case ACL_START:
7287 case ACL_START_NO_FLUSH:
7288 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007289 if (conn->rx_len) {
7290 BT_ERR("Unexpected start frame (len %d)", skb->len);
7291 kfree_skb(conn->rx_skb);
7292 conn->rx_skb = NULL;
7293 conn->rx_len = 0;
7294 l2cap_conn_unreliable(conn, ECOMM);
7295 }
7296
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03007297 /* Start fragment always begin with Basic L2CAP header */
7298 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07007299 BT_ERR("Frame is too short (len %d)", skb->len);
7300 l2cap_conn_unreliable(conn, ECOMM);
7301 goto drop;
7302 }
7303
7304 hdr = (struct l2cap_hdr *) skb->data;
7305 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
7306
7307 if (len == skb->len) {
7308 /* Complete frame received */
7309 l2cap_recv_frame(conn, skb);
7310 return 0;
7311 }
7312
7313 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
7314
7315 if (skb->len > len) {
7316 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01007317 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007318 l2cap_conn_unreliable(conn, ECOMM);
7319 goto drop;
7320 }
7321
7322 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03007323 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03007324 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007325 goto drop;
7326
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03007327 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01007328 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007329 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007330 break;
7331
7332 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007333 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
7334
7335 if (!conn->rx_len) {
7336 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
7337 l2cap_conn_unreliable(conn, ECOMM);
7338 goto drop;
7339 }
7340
7341 if (skb->len > conn->rx_len) {
7342 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01007343 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007344 kfree_skb(conn->rx_skb);
7345 conn->rx_skb = NULL;
7346 conn->rx_len = 0;
7347 l2cap_conn_unreliable(conn, ECOMM);
7348 goto drop;
7349 }
7350
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03007351 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01007352 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007353 conn->rx_len -= skb->len;
7354
7355 if (!conn->rx_len) {
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02007356 /* Complete frame received. l2cap_recv_frame
7357 * takes ownership of the skb so set the global
7358 * rx_skb pointer to NULL first.
7359 */
7360 struct sk_buff *rx_skb = conn->rx_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007361 conn->rx_skb = NULL;
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02007362 l2cap_recv_frame(conn, rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007363 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007364 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007365 }
7366
7367drop:
7368 kfree_skb(skb);
7369 return 0;
7370}
7371
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007372static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007373{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007374 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007375
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02007376 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007377
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007378 list_for_each_entry(c, &chan_list, global_l) {
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03007379 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 -07007380 &c->src, &c->dst,
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03007381 c->state, __le16_to_cpu(c->psm),
7382 c->scid, c->dcid, c->imtu, c->omtu,
7383 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02007384 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007385
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02007386 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08007387
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007388 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007389}
7390
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007391static int l2cap_debugfs_open(struct inode *inode, struct file *file)
7392{
7393 return single_open(file, l2cap_debugfs_show, inode->i_private);
7394}
7395
7396static const struct file_operations l2cap_debugfs_fops = {
7397 .open = l2cap_debugfs_open,
7398 .read = seq_read,
7399 .llseek = seq_lseek,
7400 .release = single_release,
7401};
7402
7403static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007404
Gustavo F. Padovan64274512011-02-07 20:08:52 -02007405int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007406{
7407 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08007408
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007409 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07007410 if (err < 0)
7411 return err;
7412
Marcel Holtmann1120e4b2013-10-17 17:24:16 -07007413 if (IS_ERR_OR_NULL(bt_debugfs))
7414 return 0;
7415
7416 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
7417 NULL, &l2cap_debugfs_fops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007418
Linus Torvalds1da177e2005-04-16 15:20:36 -07007419 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007420}
7421
Gustavo F. Padovan64274512011-02-07 20:08:52 -02007422void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007423{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007424 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007425 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07007426}
7427
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03007428module_param(disable_ertm, bool, 0644);
7429MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");