blob: eb5604e06106615d4f386452e6c62977a1bfcbc4 [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. Padovan710f9b0a2011-03-25 14:30:37 -030056static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +020057static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
Gustavo Padovand6603662012-05-21 13:58:22 -030059static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
Gustavo Padovan2d792812012-10-06 10:07:01 +010060 struct sk_buff_head *skbs, u8 event);
Mat Martineau608bcc62012-05-17 20:53:32 -070061
Marcel Holtmann4f1654e2013-10-13 08:50:41 -070062static inline __u8 bdaddr_type(struct hci_conn *hcon, __u8 type)
63{
64 if (hcon->type == LE_LINK) {
65 if (type == ADDR_LE_DEV_PUBLIC)
66 return BDADDR_LE_PUBLIC;
67 else
68 return BDADDR_LE_RANDOM;
69 }
70
71 return BDADDR_BREDR;
72}
73
Marcel Holtmann01394182006-07-03 10:02:46 +020074/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030075
Gustavo Padovan2d792812012-10-06 10:07:01 +010076static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
77 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020078{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020079 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030080
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020081 list_for_each_entry(c, &conn->chan_l, list) {
82 if (c->dcid == cid)
83 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020084 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020085 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020086}
87
Gustavo Padovan2d792812012-10-06 10:07:01 +010088static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
89 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020090{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020091 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030092
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020093 list_for_each_entry(c, &conn->chan_l, list) {
94 if (c->scid == cid)
95 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020096 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020097 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020098}
99
100/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -0700101 * Returns locked channel. */
Gustavo Padovan2d792812012-10-06 10:07:01 +0100102static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
103 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +0200104{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300105 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300106
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200107 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300108 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -0700109 if (c)
110 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200111 mutex_unlock(&conn->chan_lock);
112
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300113 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200114}
115
Mat Martineaub1a130b2012-10-23 15:24:09 -0700116/* Find channel with given DCID.
117 * Returns locked channel.
118 */
119static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
120 u16 cid)
121{
122 struct l2cap_chan *c;
123
124 mutex_lock(&conn->chan_lock);
125 c = __l2cap_get_chan_by_dcid(conn, cid);
126 if (c)
127 l2cap_chan_lock(c);
128 mutex_unlock(&conn->chan_lock);
129
130 return c;
131}
132
Gustavo Padovan2d792812012-10-06 10:07:01 +0100133static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
134 u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200135{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200136 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300137
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200138 list_for_each_entry(c, &conn->chan_l, list) {
139 if (c->ident == ident)
140 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200141 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200142 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200143}
144
Mat Martineau5b155ef2012-10-23 15:24:14 -0700145static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
146 u8 ident)
147{
148 struct l2cap_chan *c;
149
150 mutex_lock(&conn->chan_lock);
151 c = __l2cap_get_chan_by_ident(conn, ident);
152 if (c)
153 l2cap_chan_lock(c);
154 mutex_unlock(&conn->chan_lock);
155
156 return c;
157}
158
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300159static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300160{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300161 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300162
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300163 list_for_each_entry(c, &chan_list, global_l) {
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700164 if (c->sport == psm && !bacmp(&c->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100165 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300166 }
Szymon Janc250938c2011-11-16 09:32:22 +0100167 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300168}
169
170int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
171{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300172 int err;
173
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200174 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300175
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300176 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300177 err = -EADDRINUSE;
178 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300179 }
180
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300181 if (psm) {
182 chan->psm = psm;
183 chan->sport = psm;
184 err = 0;
185 } else {
186 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300187
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300188 err = -EINVAL;
189 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300190 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300191 chan->psm = cpu_to_le16(p);
192 chan->sport = cpu_to_le16(p);
193 err = 0;
194 break;
195 }
196 }
197
198done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200199 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300200 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300201}
202
203int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
204{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200205 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300206
207 chan->scid = scid;
208
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200209 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300210
211 return 0;
212}
213
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300214static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200215{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300216 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200217
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300218 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300219 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200220 return cid;
221 }
222
223 return 0;
224}
225
Gustavo Padovanf93fa272013-10-21 14:21:40 -0200226static void l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300227{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200228 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100229 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200230
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300231 chan->state = state;
Gustavo Padovan53f52122013-10-15 19:24:45 -0300232 chan->ops->state_change(chan, state, 0);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300233}
234
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300235static inline void l2cap_state_change_and_error(struct l2cap_chan *chan,
236 int state, int err)
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200237{
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300238 chan->state = state;
Gustavo Padovan53f52122013-10-15 19:24:45 -0300239 chan->ops->state_change(chan, chan->state, err);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200240}
241
242static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
243{
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300244 chan->ops->state_change(chan, chan->state, err);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200245}
246
Mat Martineau4239d162012-05-17 20:53:49 -0700247static void __set_retrans_timer(struct l2cap_chan *chan)
248{
249 if (!delayed_work_pending(&chan->monitor_timer) &&
250 chan->retrans_timeout) {
251 l2cap_set_timer(chan, &chan->retrans_timer,
252 msecs_to_jiffies(chan->retrans_timeout));
253 }
254}
255
256static void __set_monitor_timer(struct l2cap_chan *chan)
257{
258 __clear_retrans_timer(chan);
259 if (chan->monitor_timeout) {
260 l2cap_set_timer(chan, &chan->monitor_timer,
261 msecs_to_jiffies(chan->monitor_timeout));
262 }
263}
264
Mat Martineau608bcc62012-05-17 20:53:32 -0700265static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
266 u16 seq)
267{
268 struct sk_buff *skb;
269
270 skb_queue_walk(head, skb) {
271 if (bt_cb(skb)->control.txseq == seq)
272 return skb;
273 }
274
275 return NULL;
276}
277
Mat Martineau3c588192012-04-11 10:48:42 -0700278/* ---- L2CAP sequence number lists ---- */
279
280/* For ERTM, ordered lists of sequence numbers must be tracked for
281 * SREJ requests that are received and for frames that are to be
282 * retransmitted. These seq_list functions implement a singly-linked
283 * list in an array, where membership in the list can also be checked
284 * in constant time. Items can also be added to the tail of the list
285 * and removed from the head in constant time, without further memory
286 * allocs or frees.
287 */
288
289static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
290{
291 size_t alloc_size, i;
292
293 /* Allocated size is a power of 2 to map sequence numbers
294 * (which may be up to 14 bits) in to a smaller array that is
295 * sized for the negotiated ERTM transmit windows.
296 */
297 alloc_size = roundup_pow_of_two(size);
298
299 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
300 if (!seq_list->list)
301 return -ENOMEM;
302
303 seq_list->mask = alloc_size - 1;
304 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
305 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
306 for (i = 0; i < alloc_size; i++)
307 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
308
309 return 0;
310}
311
312static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
313{
314 kfree(seq_list->list);
315}
316
317static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
318 u16 seq)
319{
320 /* Constant-time check for list membership */
321 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
322}
323
324static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
325{
326 u16 mask = seq_list->mask;
327
328 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
329 /* In case someone tries to pop the head of an empty list */
330 return L2CAP_SEQ_LIST_CLEAR;
331 } else if (seq_list->head == seq) {
332 /* Head can be removed in constant time */
333 seq_list->head = seq_list->list[seq & mask];
334 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
335
336 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
337 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
338 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
339 }
340 } else {
341 /* Walk the list to find the sequence number */
342 u16 prev = seq_list->head;
343 while (seq_list->list[prev & mask] != seq) {
344 prev = seq_list->list[prev & mask];
345 if (prev == L2CAP_SEQ_LIST_TAIL)
346 return L2CAP_SEQ_LIST_CLEAR;
347 }
348
349 /* Unlink the number from the list and clear it */
350 seq_list->list[prev & mask] = seq_list->list[seq & mask];
351 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
352 if (seq_list->tail == seq)
353 seq_list->tail = prev;
354 }
355 return seq;
356}
357
358static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
359{
360 /* Remove the head in constant time */
361 return l2cap_seq_list_remove(seq_list, seq_list->head);
362}
363
364static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
365{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300366 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700367
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300368 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
369 return;
370
371 for (i = 0; i <= seq_list->mask; i++)
372 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
373
374 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
375 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700376}
377
378static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
379{
380 u16 mask = seq_list->mask;
381
382 /* All appends happen in constant time */
383
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300384 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
385 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700386
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300387 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
388 seq_list->head = seq;
389 else
390 seq_list->list[seq_list->tail & mask] = seq;
391
392 seq_list->tail = seq;
393 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700394}
395
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300396static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300397{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300398 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100399 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200400 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300401 int reason;
402
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200403 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300404
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200405 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200406 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300407
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300408 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300409 reason = ECONNREFUSED;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300410 else if (chan->state == BT_CONNECT &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100411 chan->sec_level != BT_SECURITY_SDP)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300412 reason = ECONNREFUSED;
413 else
414 reason = ETIMEDOUT;
415
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300416 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300417
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200418 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300419
Gustavo Padovan80b98022012-05-27 22:27:51 -0300420 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200421 mutex_unlock(&conn->chan_lock);
422
Ulisses Furquim371fd832011-12-21 20:02:36 -0200423 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300424}
425
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300426struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200427{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300428 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200429
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300430 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
431 if (!chan)
432 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200433
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200434 mutex_init(&chan->lock);
435
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200436 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300437 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200438 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300439
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300440 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300441
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300442 chan->state = BT_OPEN;
443
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530444 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300445
Mat Martineau28270112012-05-17 21:14:09 -0700446 /* This flag is cleared in l2cap_chan_ready() */
447 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
448
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300449 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100450
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300451 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200452}
453
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530454static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300455{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530456 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
457
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530458 BT_DBG("chan %p", chan);
459
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200460 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300461 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200462 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300463
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530464 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300465}
466
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530467void l2cap_chan_hold(struct l2cap_chan *c)
468{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530469 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530470
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530471 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530472}
473
474void l2cap_chan_put(struct l2cap_chan *c)
475{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530476 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530477
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530478 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530479}
480
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300481void l2cap_chan_set_defaults(struct l2cap_chan *chan)
482{
483 chan->fcs = L2CAP_FCS_CRC16;
484 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
485 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
486 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700487 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300488 chan->sec_level = BT_SECURITY_LOW;
489
490 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
491}
492
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 Hedberg3916aed2013-10-07 15:35:26 +0200500
501 if (chan->imtu < L2CAP_LE_DEFAULT_MPS)
502 chan->mps = chan->imtu;
503 else
504 chan->mps = L2CAP_LE_DEFAULT_MPS;
Johan Hedberg38319712013-05-17 12:49:23 +0300505}
506
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300507void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200508{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300509 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200510 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200511
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200512 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100513
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300514 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200515
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200516 switch (chan->chan_type) {
517 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300518 if (conn->hcon->type == LE_LINK) {
Johan Hedbergaeddd072013-10-07 16:15:25 +0200519 if (chan->dcid == L2CAP_CID_ATT) {
520 chan->omtu = L2CAP_DEFAULT_MTU;
Johan Hedberg9f22398c2013-04-29 19:35:38 +0300521 chan->scid = L2CAP_CID_ATT;
Johan Hedbergaeddd072013-10-07 16:15:25 +0200522 } else {
Johan Hedberg9f22398c2013-04-29 19:35:38 +0300523 chan->scid = l2cap_alloc_cid(conn);
Johan Hedbergaeddd072013-10-07 16:15:25 +0200524 }
Ville Tervob62f3282011-02-10 22:38:50 -0300525 } else {
526 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300527 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300528 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300529 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200530 break;
531
532 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200533 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300534 chan->scid = L2CAP_CID_CONN_LESS;
535 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300536 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200537 break;
538
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300539 case L2CAP_CHAN_CONN_FIX_A2MP:
540 chan->scid = L2CAP_CID_A2MP;
541 chan->dcid = L2CAP_CID_A2MP;
542 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
543 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
544 break;
545
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200546 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200547 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300548 chan->scid = L2CAP_CID_SIGNALING;
549 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300550 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200551 }
552
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300553 chan->local_id = L2CAP_BESTEFFORT_ID;
554 chan->local_stype = L2CAP_SERV_BESTEFFORT;
555 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
556 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
557 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300558 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300559
Ulisses Furquim371fd832011-12-21 20:02:36 -0200560 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300561
Johan Hedberg5ee98912013-04-29 19:35:43 +0300562 hci_conn_hold(conn->hcon);
563
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200564 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200565}
566
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300567void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200568{
569 mutex_lock(&conn->chan_lock);
570 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200571 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200572}
573
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300574void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200575{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300576 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200577
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300578 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200579
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300580 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200581
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900582 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300583 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300584 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200585 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200586
Ulisses Furquim371fd832011-12-21 20:02:36 -0200587 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300588
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300589 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300590
591 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
David Herrmann76a68ba2013-04-06 20:28:37 +0200592 hci_conn_drop(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300593
594 if (mgr && mgr->bredr_chan == chan)
595 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200596 }
597
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200598 if (chan->hs_hchan) {
599 struct hci_chan *hs_hchan = chan->hs_hchan;
600
601 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
602 amp_disconnect_logical_link(hs_hchan);
603 }
604
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100605 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200606
Mat Martineau28270112012-05-17 21:14:09 -0700607 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300608 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300609
Gustavo Padovanee556f62012-05-18 20:22:38 -0300610 switch(chan->mode) {
611 case L2CAP_MODE_BASIC:
612 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300613
Johan Hedberg38319712013-05-17 12:49:23 +0300614 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedberg177f8f22013-05-31 17:54:51 +0300615 skb_queue_purge(&chan->tx_q);
Johan Hedberg38319712013-05-17 12:49:23 +0300616 break;
617
Gustavo Padovanee556f62012-05-18 20:22:38 -0300618 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300619 __clear_retrans_timer(chan);
620 __clear_monitor_timer(chan);
621 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300622
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300623 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300624
Mat Martineau3c588192012-04-11 10:48:42 -0700625 l2cap_seq_list_free(&chan->srej_list);
626 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300627
628 /* fall through */
629
630 case L2CAP_MODE_STREAMING:
631 skb_queue_purge(&chan->tx_q);
632 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300633 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300634
635 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200636}
637
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300638static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan)
639{
640 struct l2cap_conn *conn = chan->conn;
641 struct l2cap_le_conn_rsp rsp;
642 u16 result;
643
644 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
645 result = L2CAP_CR_AUTHORIZATION;
646 else
647 result = L2CAP_CR_BAD_PSM;
648
649 l2cap_state_change(chan, BT_DISCONN);
650
651 rsp.dcid = cpu_to_le16(chan->scid);
652 rsp.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +0200653 rsp.mps = cpu_to_le16(chan->mps);
Johan Hedberg0cd75f72013-05-17 13:09:05 +0300654 rsp.credits = cpu_to_le16(chan->rx_credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300655 rsp.result = cpu_to_le16(result);
656
657 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
658 &rsp);
659}
660
Johan Hedberg791d60f2013-05-14 22:24:44 +0300661static void l2cap_chan_connect_reject(struct l2cap_chan *chan)
662{
663 struct l2cap_conn *conn = chan->conn;
664 struct l2cap_conn_rsp rsp;
665 u16 result;
666
667 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
668 result = L2CAP_CR_SEC_BLOCK;
669 else
670 result = L2CAP_CR_BAD_PSM;
671
672 l2cap_state_change(chan, BT_DISCONN);
673
674 rsp.scid = cpu_to_le16(chan->dcid);
675 rsp.dcid = cpu_to_le16(chan->scid);
676 rsp.result = cpu_to_le16(result);
677 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
678
679 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
680}
681
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300682void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300683{
684 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300685
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700686 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300687
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300688 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300689 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100690 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300691 break;
692
693 case BT_CONNECTED:
694 case BT_CONFIG:
Johan Hedbergcea04ce32013-05-14 22:46:01 +0300695 /* ATT uses L2CAP_CHAN_CONN_ORIENTED so we must also
696 * check for chan->psm.
697 */
698 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && chan->psm) {
Gustavo Padovan8d836d72013-10-15 19:24:47 -0300699 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200700 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300701 } else
702 l2cap_chan_del(chan, reason);
703 break;
704
705 case BT_CONNECT2:
Johan Hedberg791d60f2013-05-14 22:24:44 +0300706 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED) {
707 if (conn->hcon->type == ACL_LINK)
708 l2cap_chan_connect_reject(chan);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +0300709 else if (conn->hcon->type == LE_LINK)
710 l2cap_chan_le_connect_reject(chan);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300711 }
712
713 l2cap_chan_del(chan, reason);
714 break;
715
716 case BT_CONNECT:
717 case BT_DISCONN:
718 l2cap_chan_del(chan, reason);
719 break;
720
721 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100722 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300723 break;
724 }
725}
726
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300727static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530728{
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700729 switch (chan->chan_type) {
730 case L2CAP_CHAN_RAW:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300731 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530732 case BT_SECURITY_HIGH:
733 return HCI_AT_DEDICATED_BONDING_MITM;
734 case BT_SECURITY_MEDIUM:
735 return HCI_AT_DEDICATED_BONDING;
736 default:
737 return HCI_AT_NO_BONDING;
738 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700739 break;
Marcel Holtmann3124b842013-10-12 07:19:32 -0700740 case L2CAP_CHAN_CONN_LESS:
741 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_3DSP)) {
742 if (chan->sec_level == BT_SECURITY_LOW)
743 chan->sec_level = BT_SECURITY_SDP;
744 }
745 if (chan->sec_level == BT_SECURITY_HIGH)
746 return HCI_AT_NO_BONDING_MITM;
747 else
748 return HCI_AT_NO_BONDING;
749 break;
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700750 case L2CAP_CHAN_CONN_ORIENTED:
751 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
752 if (chan->sec_level == BT_SECURITY_LOW)
753 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530754
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700755 if (chan->sec_level == BT_SECURITY_HIGH)
756 return HCI_AT_NO_BONDING_MITM;
757 else
758 return HCI_AT_NO_BONDING;
759 }
760 /* fall through */
761 default:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300762 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530763 case BT_SECURITY_HIGH:
764 return HCI_AT_GENERAL_BONDING_MITM;
765 case BT_SECURITY_MEDIUM:
766 return HCI_AT_GENERAL_BONDING;
767 default:
768 return HCI_AT_NO_BONDING;
769 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700770 break;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530771 }
772}
773
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200774/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200775int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200776{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300777 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100778 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200779
Johan Hedberga17de2f2013-05-14 13:25:37 +0300780 if (conn->hcon->type == LE_LINK)
781 return smp_conn_security(conn->hcon, chan->sec_level);
782
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300783 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100784
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300785 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200786}
787
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200788static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200789{
790 u8 id;
791
792 /* Get next available identificator.
793 * 1 - 128 are used by kernel.
794 * 129 - 199 are reserved.
795 * 200 - 254 are used by utilities like l2ping, etc.
796 */
797
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200798 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200799
800 if (++conn->tx_ident > 128)
801 conn->tx_ident = 1;
802
803 id = conn->tx_ident;
804
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200805 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200806
807 return id;
808}
809
Gustavo Padovan2d792812012-10-06 10:07:01 +0100810static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
811 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200812{
813 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200814 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200815
816 BT_DBG("code 0x%2.2x", code);
817
818 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300819 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200820
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200821 if (lmp_no_flush_capable(conn->hcon->hdev))
822 flags = ACL_START_NO_FLUSH;
823 else
824 flags = ACL_START;
825
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700826 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200827 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700828
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200829 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200830}
831
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700832static bool __chan_is_moving(struct l2cap_chan *chan)
833{
834 return chan->move_state != L2CAP_MOVE_STABLE &&
835 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
836}
837
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200838static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
839{
840 struct hci_conn *hcon = chan->conn->hcon;
841 u16 flags;
842
843 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100844 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200845
Mat Martineaud5f8a752012-10-23 15:24:18 -0700846 if (chan->hs_hcon && !__chan_is_moving(chan)) {
847 if (chan->hs_hchan)
848 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
849 else
850 kfree_skb(skb);
851
852 return;
853 }
854
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200855 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100856 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200857 flags = ACL_START_NO_FLUSH;
858 else
859 flags = ACL_START;
860
861 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
862 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863}
864
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700865static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
866{
867 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
868 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
869
870 if (enh & L2CAP_CTRL_FRAME_TYPE) {
871 /* S-Frame */
872 control->sframe = 1;
873 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
874 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
875
876 control->sar = 0;
877 control->txseq = 0;
878 } else {
879 /* I-Frame */
880 control->sframe = 0;
881 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
882 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
883
884 control->poll = 0;
885 control->super = 0;
886 }
887}
888
889static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
890{
891 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
892 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
893
894 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
895 /* S-Frame */
896 control->sframe = 1;
897 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
898 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
899
900 control->sar = 0;
901 control->txseq = 0;
902 } else {
903 /* I-Frame */
904 control->sframe = 0;
905 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
906 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
907
908 control->poll = 0;
909 control->super = 0;
910 }
911}
912
913static inline void __unpack_control(struct l2cap_chan *chan,
914 struct sk_buff *skb)
915{
916 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
917 __unpack_extended_control(get_unaligned_le32(skb->data),
918 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700919 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700920 } else {
921 __unpack_enhanced_control(get_unaligned_le16(skb->data),
922 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700923 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700924 }
925}
926
927static u32 __pack_extended_control(struct l2cap_ctrl *control)
928{
929 u32 packed;
930
931 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
932 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
933
934 if (control->sframe) {
935 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
936 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
937 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
938 } else {
939 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
940 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
941 }
942
943 return packed;
944}
945
946static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
947{
948 u16 packed;
949
950 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
951 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
952
953 if (control->sframe) {
954 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
955 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
956 packed |= L2CAP_CTRL_FRAME_TYPE;
957 } else {
958 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
959 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
960 }
961
962 return packed;
963}
964
965static inline void __pack_control(struct l2cap_chan *chan,
966 struct l2cap_ctrl *control,
967 struct sk_buff *skb)
968{
969 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
970 put_unaligned_le32(__pack_extended_control(control),
971 skb->data + L2CAP_HDR_SIZE);
972 } else {
973 put_unaligned_le16(__pack_enhanced_control(control),
974 skb->data + L2CAP_HDR_SIZE);
975 }
976}
977
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300978static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
979{
980 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
981 return L2CAP_EXT_HDR_SIZE;
982 else
983 return L2CAP_ENH_HDR_SIZE;
984}
985
Mat Martineaua67d7f62012-05-17 20:53:35 -0700986static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
987 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300988{
989 struct sk_buff *skb;
990 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300991 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300992
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300993 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300994 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300995
Mat Martineaua67d7f62012-05-17 20:53:35 -0700996 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300997
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300998 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700999 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001000
1001 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001002 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001003 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03001004
Mat Martineaua67d7f62012-05-17 20:53:35 -07001005 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1006 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
1007 else
1008 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001009
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001010 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -07001011 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03001012 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001013 }
1014
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001015 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -07001016 return skb;
1017}
1018
1019static void l2cap_send_sframe(struct l2cap_chan *chan,
1020 struct l2cap_ctrl *control)
1021{
1022 struct sk_buff *skb;
1023 u32 control_field;
1024
1025 BT_DBG("chan %p, control %p", chan, control);
1026
1027 if (!control->sframe)
1028 return;
1029
Mat Martineaub99e13a2012-10-23 15:24:19 -07001030 if (__chan_is_moving(chan))
1031 return;
1032
Mat Martineaua67d7f62012-05-17 20:53:35 -07001033 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
1034 !control->poll)
1035 control->final = 1;
1036
1037 if (control->super == L2CAP_SUPER_RR)
1038 clear_bit(CONN_RNR_SENT, &chan->conn_state);
1039 else if (control->super == L2CAP_SUPER_RNR)
1040 set_bit(CONN_RNR_SENT, &chan->conn_state);
1041
1042 if (control->super != L2CAP_SUPER_SREJ) {
1043 chan->last_acked_seq = control->reqseq;
1044 __clear_ack_timer(chan);
1045 }
1046
1047 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
1048 control->final, control->poll, control->super);
1049
1050 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1051 control_field = __pack_extended_control(control);
1052 else
1053 control_field = __pack_enhanced_control(control);
1054
1055 skb = l2cap_create_sframe_pdu(chan, control_field);
1056 if (!IS_ERR(skb))
1057 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001058}
1059
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001060static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001061{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001062 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001063
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001064 BT_DBG("chan %p, poll %d", chan, poll);
1065
1066 memset(&control, 0, sizeof(control));
1067 control.sframe = 1;
1068 control.poll = poll;
1069
1070 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
1071 control.super = L2CAP_SUPER_RNR;
1072 else
1073 control.super = L2CAP_SUPER_RR;
1074
1075 control.reqseq = chan->buffer_seq;
1076 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001077}
1078
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001079static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001080{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001081 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001082}
1083
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001084static bool __amp_capable(struct l2cap_chan *chan)
1085{
1086 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001087 struct hci_dev *hdev;
1088 bool amp_available = false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001089
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001090 if (!conn->hs_enabled)
1091 return false;
1092
1093 if (!(conn->fixed_chan_mask & L2CAP_FC_A2MP))
1094 return false;
1095
1096 read_lock(&hci_dev_list_lock);
1097 list_for_each_entry(hdev, &hci_dev_list, list) {
1098 if (hdev->amp_type != AMP_TYPE_BREDR &&
1099 test_bit(HCI_UP, &hdev->flags)) {
1100 amp_available = true;
1101 break;
1102 }
1103 }
1104 read_unlock(&hci_dev_list_lock);
1105
1106 if (chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED)
1107 return amp_available;
Marcel Holtmann848566b2013-10-01 22:59:22 -07001108
1109 return false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001110}
1111
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001112static bool l2cap_check_efs(struct l2cap_chan *chan)
1113{
1114 /* Check EFS parameters */
1115 return true;
1116}
1117
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001118void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001119{
1120 struct l2cap_conn *conn = chan->conn;
1121 struct l2cap_conn_req req;
1122
1123 req.scid = cpu_to_le16(chan->scid);
1124 req.psm = chan->psm;
1125
1126 chan->ident = l2cap_get_ident(conn);
1127
1128 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1129
1130 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1131}
1132
Mat Martineau8eb200b2012-10-23 15:24:17 -07001133static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1134{
1135 struct l2cap_create_chan_req req;
1136 req.scid = cpu_to_le16(chan->scid);
1137 req.psm = chan->psm;
1138 req.amp_id = amp_id;
1139
1140 chan->ident = l2cap_get_ident(chan->conn);
1141
1142 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1143 sizeof(req), &req);
1144}
1145
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001146static void l2cap_move_setup(struct l2cap_chan *chan)
1147{
1148 struct sk_buff *skb;
1149
1150 BT_DBG("chan %p", chan);
1151
1152 if (chan->mode != L2CAP_MODE_ERTM)
1153 return;
1154
1155 __clear_retrans_timer(chan);
1156 __clear_monitor_timer(chan);
1157 __clear_ack_timer(chan);
1158
1159 chan->retry_count = 0;
1160 skb_queue_walk(&chan->tx_q, skb) {
1161 if (bt_cb(skb)->control.retries)
1162 bt_cb(skb)->control.retries = 1;
1163 else
1164 break;
1165 }
1166
1167 chan->expected_tx_seq = chan->buffer_seq;
1168
1169 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1170 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1171 l2cap_seq_list_clear(&chan->retrans_list);
1172 l2cap_seq_list_clear(&chan->srej_list);
1173 skb_queue_purge(&chan->srej_q);
1174
1175 chan->tx_state = L2CAP_TX_STATE_XMIT;
1176 chan->rx_state = L2CAP_RX_STATE_MOVE;
1177
1178 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1179}
1180
Mat Martineau5f3847a2012-10-23 15:24:12 -07001181static void l2cap_move_done(struct l2cap_chan *chan)
1182{
1183 u8 move_role = chan->move_role;
1184 BT_DBG("chan %p", chan);
1185
1186 chan->move_state = L2CAP_MOVE_STABLE;
1187 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1188
1189 if (chan->mode != L2CAP_MODE_ERTM)
1190 return;
1191
1192 switch (move_role) {
1193 case L2CAP_MOVE_ROLE_INITIATOR:
1194 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1195 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1196 break;
1197 case L2CAP_MOVE_ROLE_RESPONDER:
1198 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1199 break;
1200 }
1201}
1202
Johan Hedberg177f8f22013-05-31 17:54:51 +03001203static void l2cap_le_flowctl_start(struct l2cap_chan *chan)
1204{
1205 chan->sdu = NULL;
1206 chan->sdu_last_frag = NULL;
1207 chan->sdu_len = 0;
1208
Johan Hedberg3916aed2013-10-07 15:35:26 +02001209 if (chan->imtu < L2CAP_LE_DEFAULT_MPS)
1210 chan->mps = chan->imtu;
1211 else
1212 chan->mps = L2CAP_LE_DEFAULT_MPS;
1213
Johan Hedberg177f8f22013-05-31 17:54:51 +03001214 skb_queue_head_init(&chan->tx_q);
Johan Hedberg029727a2013-10-07 14:44:48 +02001215
1216 if (!chan->tx_credits)
1217 chan->ops->suspend(chan);
Johan Hedberg177f8f22013-05-31 17:54:51 +03001218}
1219
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001220static void l2cap_chan_ready(struct l2cap_chan *chan)
1221{
Mat Martineau28270112012-05-17 21:14:09 -07001222 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001223 chan->conf_state = 0;
1224 __clear_chan_timer(chan);
1225
Johan Hedberg177f8f22013-05-31 17:54:51 +03001226 if (chan->mode == L2CAP_MODE_LE_FLOWCTL)
1227 l2cap_le_flowctl_start(chan);
1228
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001229 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001230
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001231 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001232}
1233
Johan Hedbergf1496de2013-05-13 14:15:56 +03001234static void l2cap_le_connect(struct l2cap_chan *chan)
1235{
1236 struct l2cap_conn *conn = chan->conn;
1237 struct l2cap_le_conn_req req;
1238
Johan Hedberg595177f2013-12-02 22:12:22 +02001239 if (test_and_set_bit(FLAG_LE_CONN_REQ_SENT, &chan->flags))
1240 return;
1241
Johan Hedbergf1496de2013-05-13 14:15:56 +03001242 req.psm = chan->psm;
1243 req.scid = cpu_to_le16(chan->scid);
1244 req.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +02001245 req.mps = cpu_to_le16(chan->mps);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03001246 req.credits = cpu_to_le16(chan->rx_credits);
Johan Hedbergf1496de2013-05-13 14:15:56 +03001247
1248 chan->ident = l2cap_get_ident(conn);
1249
1250 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_REQ,
1251 sizeof(req), &req);
1252}
1253
1254static void l2cap_le_start(struct l2cap_chan *chan)
1255{
1256 struct l2cap_conn *conn = chan->conn;
1257
1258 if (!smp_conn_security(conn->hcon, chan->sec_level))
1259 return;
1260
1261 if (!chan->psm) {
1262 l2cap_chan_ready(chan);
1263 return;
1264 }
1265
1266 if (chan->state == BT_CONNECT)
1267 l2cap_le_connect(chan);
1268}
1269
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001270static void l2cap_start_connection(struct l2cap_chan *chan)
1271{
1272 if (__amp_capable(chan)) {
1273 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1274 a2mp_discover_amp(chan);
Johan Hedbergf1496de2013-05-13 14:15:56 +03001275 } else if (chan->conn->hcon->type == LE_LINK) {
1276 l2cap_le_start(chan);
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001277 } else {
1278 l2cap_send_conn_req(chan);
1279 }
1280}
1281
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001282static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001283{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001284 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001285
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001286 if (conn->hcon->type == LE_LINK) {
Johan Hedberg96ac34f2013-05-13 11:15:07 +03001287 l2cap_le_start(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001288 return;
1289 }
1290
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001291 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001292 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1293 return;
1294
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001295 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001296 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001297 l2cap_start_connection(chan);
1298 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001299 } else {
1300 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001301 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001302
1303 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1304 conn->info_ident = l2cap_get_ident(conn);
1305
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001306 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001307
Gustavo Padovan2d792812012-10-06 10:07:01 +01001308 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1309 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001310 }
1311}
1312
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001313static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1314{
1315 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001316 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001317 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1318
1319 switch (mode) {
1320 case L2CAP_MODE_ERTM:
1321 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1322 case L2CAP_MODE_STREAMING:
1323 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1324 default:
1325 return 0x00;
1326 }
1327}
1328
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001329static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001330{
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001331 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001332 struct l2cap_disconn_req req;
1333
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001334 if (!conn)
1335 return;
1336
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001337 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001338 __clear_retrans_timer(chan);
1339 __clear_monitor_timer(chan);
1340 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001341 }
1342
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001343 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001344 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001345 return;
1346 }
1347
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001348 req.dcid = cpu_to_le16(chan->dcid);
1349 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001350 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1351 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001352
Gustavo Padovanf8e73012013-10-15 19:24:46 -03001353 l2cap_state_change_and_error(chan, BT_DISCONN, err);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001354}
1355
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001357static void l2cap_conn_start(struct l2cap_conn *conn)
1358{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001359 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001360
1361 BT_DBG("conn %p", conn);
1362
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001363 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001364
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001365 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001366 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001367
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001368 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001369 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001370 continue;
1371 }
1372
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001373 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001374 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001375 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001376 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001377 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001378 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001379
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001380 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001381 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001382 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001383 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001384 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001385 continue;
1386 }
1387
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001388 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001389
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001390 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001391 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001392 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001393 rsp.scid = cpu_to_le16(chan->dcid);
1394 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001395
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001396 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07001397 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001398 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1399 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001400 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001401
1402 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02001403 l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001404 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1405 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001406 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001407 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001408 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1409 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001410 }
1411
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001412 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001413 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001414
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001415 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001416 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001417 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001418 continue;
1419 }
1420
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001421 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001422 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001423 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001424 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001425 }
1426
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001427 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001428 }
1429
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001430 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001431}
1432
Ido Yarivc2287682012-04-20 15:46:07 -03001433/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001434 * Returns closest match, locked.
1435 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001436static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001437 bdaddr_t *src,
1438 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001439{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001440 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001441
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001442 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001443
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001444 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001445 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001446 continue;
1447
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001448 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001449 int src_match, dst_match;
1450 int src_any, dst_any;
1451
Ville Tervob62f3282011-02-10 22:38:50 -03001452 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001453 src_match = !bacmp(&c->src, src);
1454 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001455 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001456 read_unlock(&chan_list_lock);
1457 return c;
1458 }
Ville Tervob62f3282011-02-10 22:38:50 -03001459
1460 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001461 src_any = !bacmp(&c->src, BDADDR_ANY);
1462 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001463 if ((src_match && dst_any) || (src_any && dst_match) ||
1464 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001465 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001466 }
1467 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001468
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001469 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001470
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001471 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001472}
1473
1474static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1475{
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001476 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001477 struct l2cap_chan *chan, *pchan;
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001478 u8 dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001479
1480 BT_DBG("");
1481
1482 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001483 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001484 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001485 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001486 return;
1487
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001488 /* Client ATT sockets should override the server one */
1489 if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
1490 return;
1491
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001492 dst_type = bdaddr_type(hcon, hcon->dst_type);
1493
1494 /* If device is blocked, do not create a channel for it */
1495 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, dst_type))
1496 return;
1497
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001498 l2cap_chan_lock(pchan);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001499
Gustavo Padovan80b98022012-05-27 22:27:51 -03001500 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001501 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001502 goto clean;
1503
Johan Hedberg9f22398c2013-04-29 19:35:38 +03001504 chan->dcid = L2CAP_CID_ATT;
1505
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001506 bacpy(&chan->src, &hcon->src);
1507 bacpy(&chan->dst, &hcon->dst);
1508 chan->src_type = bdaddr_type(hcon, hcon->src_type);
1509 chan->dst_type = dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001510
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001511 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001512
Ville Tervob62f3282011-02-10 22:38:50 -03001513clean:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02001514 l2cap_chan_unlock(pchan);
Ville Tervob62f3282011-02-10 22:38:50 -03001515}
1516
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001517static void l2cap_conn_ready(struct l2cap_conn *conn)
1518{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001519 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001520 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001521
1522 BT_DBG("conn %p", conn);
1523
Johan Hedbergd8729922013-04-29 19:35:39 +03001524 /* For outgoing pairing which doesn't necessarily have an
1525 * associated socket (e.g. mgmt_pair_device).
1526 */
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001527 if (hcon->out && hcon->type == LE_LINK)
1528 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001529
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001530 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001531
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001532 if (hcon->type == LE_LINK)
1533 l2cap_le_conn_ready(conn);
1534
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001535 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001536
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001537 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001538
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001539 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1540 l2cap_chan_unlock(chan);
1541 continue;
1542 }
1543
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001544 if (hcon->type == LE_LINK) {
Johan Hedbergf1496de2013-05-13 14:15:56 +03001545 l2cap_le_start(chan);
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001546 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo Padovan74e75742013-10-15 19:24:51 -03001547 l2cap_chan_ready(chan);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001548
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001549 } else if (chan->state == BT_CONNECT) {
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001550 l2cap_do_start(chan);
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001551 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001552
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001553 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001554 }
1555
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001556 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001557}
1558
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001559/* Notify sockets that we cannot guaranty reliability anymore */
1560static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1561{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001562 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001563
1564 BT_DBG("conn %p", conn);
1565
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001566 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001567
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001568 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001569 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001570 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001571 }
1572
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001573 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001574}
1575
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001576static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001577{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001578 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001579 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001580
Marcel Holtmann984947d2009-02-06 23:35:19 +01001581 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001582 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001583
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001584 l2cap_conn_start(conn);
1585}
1586
David Herrmann2c8e1412013-04-06 20:28:45 +02001587/*
1588 * l2cap_user
1589 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1590 * callback is called during registration. The ->remove callback is called
1591 * during unregistration.
1592 * An l2cap_user object can either be explicitly unregistered or when the
1593 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1594 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1595 * External modules must own a reference to the l2cap_conn object if they intend
1596 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1597 * any time if they don't.
1598 */
1599
1600int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1601{
1602 struct hci_dev *hdev = conn->hcon->hdev;
1603 int ret;
1604
1605 /* We need to check whether l2cap_conn is registered. If it is not, we
1606 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1607 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1608 * relies on the parent hci_conn object to be locked. This itself relies
1609 * on the hci_dev object to be locked. So we must lock the hci device
1610 * here, too. */
1611
1612 hci_dev_lock(hdev);
1613
1614 if (user->list.next || user->list.prev) {
1615 ret = -EINVAL;
1616 goto out_unlock;
1617 }
1618
1619 /* conn->hchan is NULL after l2cap_conn_del() was called */
1620 if (!conn->hchan) {
1621 ret = -ENODEV;
1622 goto out_unlock;
1623 }
1624
1625 ret = user->probe(conn, user);
1626 if (ret)
1627 goto out_unlock;
1628
1629 list_add(&user->list, &conn->users);
1630 ret = 0;
1631
1632out_unlock:
1633 hci_dev_unlock(hdev);
1634 return ret;
1635}
1636EXPORT_SYMBOL(l2cap_register_user);
1637
1638void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1639{
1640 struct hci_dev *hdev = conn->hcon->hdev;
1641
1642 hci_dev_lock(hdev);
1643
1644 if (!user->list.next || !user->list.prev)
1645 goto out_unlock;
1646
1647 list_del(&user->list);
1648 user->list.next = NULL;
1649 user->list.prev = NULL;
1650 user->remove(conn, user);
1651
1652out_unlock:
1653 hci_dev_unlock(hdev);
1654}
1655EXPORT_SYMBOL(l2cap_unregister_user);
1656
1657static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1658{
1659 struct l2cap_user *user;
1660
1661 while (!list_empty(&conn->users)) {
1662 user = list_first_entry(&conn->users, struct l2cap_user, list);
1663 list_del(&user->list);
1664 user->list.next = NULL;
1665 user->list.prev = NULL;
1666 user->remove(conn, user);
1667 }
1668}
1669
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001670static void l2cap_conn_del(struct hci_conn *hcon, int err)
1671{
1672 struct l2cap_conn *conn = hcon->l2cap_data;
1673 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001674
1675 if (!conn)
1676 return;
1677
1678 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1679
1680 kfree_skb(conn->rx_skb);
1681
David Herrmann2c8e1412013-04-06 20:28:45 +02001682 l2cap_unregister_all_users(conn);
1683
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001684 mutex_lock(&conn->chan_lock);
1685
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001686 /* Kill channels */
1687 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001688 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001689 l2cap_chan_lock(chan);
1690
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001691 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001692
1693 l2cap_chan_unlock(chan);
1694
Gustavo Padovan80b98022012-05-27 22:27:51 -03001695 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001696 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001697 }
1698
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001699 mutex_unlock(&conn->chan_lock);
1700
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001701 hci_chan_del(conn->hchan);
1702
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001703 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001704 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001705
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001706 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001707 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001708 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001709 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001710
1711 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001712 conn->hchan = NULL;
1713 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001714}
1715
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001716static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001717{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001718 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001719 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001720
Johan Hedbergd06cc412012-06-06 18:44:11 +08001721 BT_DBG("conn %p", conn);
1722
1723 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1724 smp_chan_destroy(conn);
1725 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1726 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001727}
1728
Claudio Takahasibaf43252013-04-11 13:55:50 -03001729static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730{
Marcel Holtmann01394182006-07-03 10:02:46 +02001731 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001732 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733
Claudio Takahasibaf43252013-04-11 13:55:50 -03001734 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735 return conn;
1736
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001737 hchan = hci_chan_create(hcon);
1738 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001741 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001742 if (!conn) {
1743 hci_chan_del(hchan);
1744 return NULL;
1745 }
1746
David Herrmann9c903e32013-04-06 20:28:44 +02001747 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001748 hcon->l2cap_data = conn;
1749 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001750 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001751 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001753 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001754
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001755 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001756 case LE_LINK:
1757 if (hcon->hdev->le_mtu) {
1758 conn->mtu = hcon->hdev->le_mtu;
1759 break;
1760 }
1761 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001762 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001763 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001764 break;
1765 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001766
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001767 conn->feat_mask = 0;
1768
Marcel Holtmann848566b2013-10-01 22:59:22 -07001769 if (hcon->type == ACL_LINK)
1770 conn->hs_enabled = test_bit(HCI_HS_ENABLED,
1771 &hcon->hdev->dev_flags);
1772
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001774 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001775
1776 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001777 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001779 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001780 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001781 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001782 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001783
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001784 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001785
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786 return conn;
1787}
1788
David Herrmann9c903e32013-04-06 20:28:44 +02001789static void l2cap_conn_free(struct kref *ref)
1790{
1791 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1792
1793 hci_conn_put(conn->hcon);
1794 kfree(conn);
1795}
1796
1797void l2cap_conn_get(struct l2cap_conn *conn)
1798{
1799 kref_get(&conn->ref);
1800}
1801EXPORT_SYMBOL(l2cap_conn_get);
1802
1803void l2cap_conn_put(struct l2cap_conn *conn)
1804{
1805 kref_put(&conn->ref, l2cap_conn_free);
1806}
1807EXPORT_SYMBOL(l2cap_conn_put);
1808
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810
Ido Yarivc2287682012-04-20 15:46:07 -03001811/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812 * Returns closest match.
1813 */
Ido Yarivc2287682012-04-20 15:46:07 -03001814static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1815 bdaddr_t *src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001816 bdaddr_t *dst,
1817 u8 link_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001819 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001821 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001822
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001823 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001824 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825 continue;
1826
Johan Hedbergbf20fd42013-05-14 13:23:13 +03001827 if (link_type == ACL_LINK && c->src_type != BDADDR_BREDR)
1828 continue;
1829
1830 if (link_type == LE_LINK && c->src_type == BDADDR_BREDR)
1831 continue;
1832
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001833 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001834 int src_match, dst_match;
1835 int src_any, dst_any;
1836
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001838 src_match = !bacmp(&c->src, src);
1839 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001840 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001841 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001842 return c;
1843 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844
1845 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001846 src_any = !bacmp(&c->src, BDADDR_ANY);
1847 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001848 if ((src_match && dst_any) || (src_any && dst_match) ||
1849 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001850 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851 }
1852 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001854 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001855
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001856 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857}
1858
Andre Guedes8e9f9892012-04-24 21:02:55 -03001859int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1860 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001861{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862 struct l2cap_conn *conn;
1863 struct hci_conn *hcon;
1864 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001865 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001866 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001868 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301869 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001871 hdev = hci_get_route(dst, &chan->src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001872 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873 return -EHOSTUNREACH;
1874
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001875 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001877 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001878
1879 /* PSM must be odd and lsb of upper byte must be 0 */
1880 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001881 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001882 err = -EINVAL;
1883 goto done;
1884 }
1885
1886 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1887 err = -EINVAL;
1888 goto done;
1889 }
1890
1891 switch (chan->mode) {
1892 case L2CAP_MODE_BASIC:
Johan Hedberg38319712013-05-17 12:49:23 +03001893 case L2CAP_MODE_LE_FLOWCTL:
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001894 break;
1895 case L2CAP_MODE_ERTM:
1896 case L2CAP_MODE_STREAMING:
1897 if (!disable_ertm)
1898 break;
1899 /* fall through */
1900 default:
1901 err = -ENOTSUPP;
1902 goto done;
1903 }
1904
Gustavo Padovan0797e012012-05-27 22:27:54 -03001905 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001906 case BT_CONNECT:
1907 case BT_CONNECT2:
1908 case BT_CONFIG:
1909 /* Already connecting */
1910 err = 0;
1911 goto done;
1912
1913 case BT_CONNECTED:
1914 /* Already connected */
1915 err = -EISCONN;
1916 goto done;
1917
1918 case BT_OPEN:
1919 case BT_BOUND:
1920 /* Can connect */
1921 break;
1922
1923 default:
1924 err = -EBADFD;
1925 goto done;
1926 }
1927
1928 /* Set destination address and psm */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001929 bacpy(&chan->dst, dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001930 chan->dst_type = dst_type;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001931
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001932 chan->psm = psm;
1933 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001935 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001936
Johan Hedbergf224ca52013-04-29 19:35:36 +03001937 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001938 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001939 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001940 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001941 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001942 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001943
Ville Tervo30e76272011-02-22 16:10:53 -03001944 if (IS_ERR(hcon)) {
1945 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001947 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948
Claudio Takahasibaf43252013-04-11 13:55:50 -03001949 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001951 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001952 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001953 goto done;
1954 }
1955
Johan Hedberg141d5702013-04-29 19:35:37 +03001956 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1957 hci_conn_drop(hcon);
1958 err = -EBUSY;
1959 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001960 }
1961
Linus Torvalds1da177e2005-04-16 15:20:36 -07001962 /* Update source addr of the socket */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001963 bacpy(&chan->src, &hcon->src);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001964 chan->src_type = bdaddr_type(hcon, hcon->src_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001966 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001967 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001968 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001969
Johan Hedberg5ee98912013-04-29 19:35:43 +03001970 /* l2cap_chan_add takes its own ref so we can drop this one */
1971 hci_conn_drop(hcon);
1972
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001973 l2cap_state_change(chan, BT_CONNECT);
Gustavo Padovan8d836d72013-10-15 19:24:47 -03001974 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001975
1976 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001977 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001978 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001979 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001980 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001981 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001982 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001983 }
1984
Ville Tervo30e76272011-02-22 16:10:53 -03001985 err = 0;
1986
Linus Torvalds1da177e2005-04-16 15:20:36 -07001987done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001988 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001989 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001990 hci_dev_put(hdev);
1991 return err;
1992}
1993
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001994static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001995{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001996 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001997 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001998
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001999 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03002000
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002001 l2cap_chan_lock(chan);
2002
Mat Martineau80909e02012-05-17 20:53:50 -07002003 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002004 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02002005 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002006 return;
2007 }
2008
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002009 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002010
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002011 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02002012 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002013}
2014
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002015static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002016{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002017 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07002018 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002019
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03002020 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03002021
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002022 l2cap_chan_lock(chan);
2023
Mat Martineau80909e02012-05-17 20:53:50 -07002024 if (!chan->conn) {
2025 l2cap_chan_unlock(chan);
2026 l2cap_chan_put(chan);
2027 return;
2028 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002029
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002030 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002031 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02002032 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002033}
2034
Gustavo Padovand6603662012-05-21 13:58:22 -03002035static void l2cap_streaming_send(struct l2cap_chan *chan,
2036 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002037{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03002038 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07002039 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002040
Mat Martineau37339372012-05-17 20:53:33 -07002041 BT_DBG("chan %p, skbs %p", chan, skbs);
2042
Mat Martineaub99e13a2012-10-23 15:24:19 -07002043 if (__chan_is_moving(chan))
2044 return;
2045
Mat Martineau37339372012-05-17 20:53:33 -07002046 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2047
2048 while (!skb_queue_empty(&chan->tx_q)) {
2049
2050 skb = skb_dequeue(&chan->tx_q);
2051
2052 bt_cb(skb)->control.retries = 1;
2053 control = &bt_cb(skb)->control;
2054
2055 control->reqseq = 0;
2056 control->txseq = chan->next_tx_seq;
2057
2058 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002059
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002060 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07002061 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2062 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002063 }
2064
Gustavo F. Padovan43434782011-04-12 18:31:57 -03002065 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002066
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002067 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07002068
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002069 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07002070 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002071 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03002072}
2073
Szymon Janc67c9e842011-07-28 16:24:33 +02002074static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002075{
2076 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07002077 struct l2cap_ctrl *control;
2078 int sent = 0;
2079
2080 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002081
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03002082 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03002083 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002084
Mat Martineau94122bb2012-05-02 09:42:02 -07002085 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2086 return 0;
2087
Mat Martineaub99e13a2012-10-23 15:24:19 -07002088 if (__chan_is_moving(chan))
2089 return 0;
2090
Mat Martineau18a48e72012-05-17 20:53:34 -07002091 while (chan->tx_send_head &&
2092 chan->unacked_frames < chan->remote_tx_win &&
2093 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002094
Mat Martineau18a48e72012-05-17 20:53:34 -07002095 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002096
Mat Martineau18a48e72012-05-17 20:53:34 -07002097 bt_cb(skb)->control.retries = 1;
2098 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03002099
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002100 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07002101 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002102
Mat Martineau18a48e72012-05-17 20:53:34 -07002103 control->reqseq = chan->buffer_seq;
2104 chan->last_acked_seq = chan->buffer_seq;
2105 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002106
Mat Martineau18a48e72012-05-17 20:53:34 -07002107 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002108
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002109 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07002110 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2111 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002112 }
2113
Mat Martineau18a48e72012-05-17 20:53:34 -07002114 /* Clone after data has been modified. Data is assumed to be
2115 read-only (for locking purposes) on cloned sk_buffs.
2116 */
2117 tx_skb = skb_clone(skb, GFP_KERNEL);
2118
2119 if (!tx_skb)
2120 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002121
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002122 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002123
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002124 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002125 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002126 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002127 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002128
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002129 if (skb_queue_is_last(&chan->tx_q, skb))
2130 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002131 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002132 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002133
2134 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002135 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002136 }
2137
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002138 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2139 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002140
2141 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002142}
2143
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002144static void l2cap_ertm_resend(struct l2cap_chan *chan)
2145{
2146 struct l2cap_ctrl control;
2147 struct sk_buff *skb;
2148 struct sk_buff *tx_skb;
2149 u16 seq;
2150
2151 BT_DBG("chan %p", chan);
2152
2153 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2154 return;
2155
Mat Martineaub99e13a2012-10-23 15:24:19 -07002156 if (__chan_is_moving(chan))
2157 return;
2158
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002159 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2160 seq = l2cap_seq_list_pop(&chan->retrans_list);
2161
2162 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2163 if (!skb) {
2164 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002165 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002166 continue;
2167 }
2168
2169 bt_cb(skb)->control.retries++;
2170 control = bt_cb(skb)->control;
2171
2172 if (chan->max_tx != 0 &&
2173 bt_cb(skb)->control.retries > chan->max_tx) {
2174 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002175 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002176 l2cap_seq_list_clear(&chan->retrans_list);
2177 break;
2178 }
2179
2180 control.reqseq = chan->buffer_seq;
2181 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2182 control.final = 1;
2183 else
2184 control.final = 0;
2185
2186 if (skb_cloned(skb)) {
2187 /* Cloned sk_buffs are read-only, so we need a
2188 * writeable copy
2189 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002190 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002191 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002192 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002193 }
2194
2195 if (!tx_skb) {
2196 l2cap_seq_list_clear(&chan->retrans_list);
2197 break;
2198 }
2199
2200 /* Update skb contents */
2201 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2202 put_unaligned_le32(__pack_extended_control(&control),
2203 tx_skb->data + L2CAP_HDR_SIZE);
2204 } else {
2205 put_unaligned_le16(__pack_enhanced_control(&control),
2206 tx_skb->data + L2CAP_HDR_SIZE);
2207 }
2208
2209 if (chan->fcs == L2CAP_FCS_CRC16) {
2210 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2211 put_unaligned_le16(fcs, skb_put(tx_skb,
2212 L2CAP_FCS_SIZE));
2213 }
2214
2215 l2cap_do_send(chan, tx_skb);
2216
2217 BT_DBG("Resent txseq %d", control.txseq);
2218
2219 chan->last_acked_seq = chan->buffer_seq;
2220 }
2221}
2222
Mat Martineauf80842a2012-05-17 20:53:46 -07002223static void l2cap_retransmit(struct l2cap_chan *chan,
2224 struct l2cap_ctrl *control)
2225{
2226 BT_DBG("chan %p, control %p", chan, control);
2227
2228 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2229 l2cap_ertm_resend(chan);
2230}
2231
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002232static void l2cap_retransmit_all(struct l2cap_chan *chan,
2233 struct l2cap_ctrl *control)
2234{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002235 struct sk_buff *skb;
2236
2237 BT_DBG("chan %p, control %p", chan, control);
2238
2239 if (control->poll)
2240 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2241
2242 l2cap_seq_list_clear(&chan->retrans_list);
2243
2244 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2245 return;
2246
2247 if (chan->unacked_frames) {
2248 skb_queue_walk(&chan->tx_q, skb) {
2249 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002250 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002251 break;
2252 }
2253
2254 skb_queue_walk_from(&chan->tx_q, skb) {
2255 if (skb == chan->tx_send_head)
2256 break;
2257
2258 l2cap_seq_list_append(&chan->retrans_list,
2259 bt_cb(skb)->control.txseq);
2260 }
2261
2262 l2cap_ertm_resend(chan);
2263 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002264}
2265
Szymon Jancb17e73b2012-01-11 10:59:47 +01002266static void l2cap_send_ack(struct l2cap_chan *chan)
2267{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002268 struct l2cap_ctrl control;
2269 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2270 chan->last_acked_seq);
2271 int threshold;
2272
2273 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2274 chan, chan->last_acked_seq, chan->buffer_seq);
2275
2276 memset(&control, 0, sizeof(control));
2277 control.sframe = 1;
2278
2279 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2280 chan->rx_state == L2CAP_RX_STATE_RECV) {
2281 __clear_ack_timer(chan);
2282 control.super = L2CAP_SUPER_RNR;
2283 control.reqseq = chan->buffer_seq;
2284 l2cap_send_sframe(chan, &control);
2285 } else {
2286 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2287 l2cap_ertm_send(chan);
2288 /* If any i-frames were sent, they included an ack */
2289 if (chan->buffer_seq == chan->last_acked_seq)
2290 frames_to_ack = 0;
2291 }
2292
Mat Martineauc20f8e32012-07-10 05:47:07 -07002293 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002294 * Calculate without mul or div
2295 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002296 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002297 threshold += threshold << 1;
2298 threshold >>= 2;
2299
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002300 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002301 threshold);
2302
2303 if (frames_to_ack >= threshold) {
2304 __clear_ack_timer(chan);
2305 control.super = L2CAP_SUPER_RR;
2306 control.reqseq = chan->buffer_seq;
2307 l2cap_send_sframe(chan, &control);
2308 frames_to_ack = 0;
2309 }
2310
2311 if (frames_to_ack)
2312 __set_ack_timer(chan);
2313 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002314}
2315
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002316static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2317 struct msghdr *msg, int len,
2318 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002320 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002321 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002322 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002324 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002325 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002326
2327 sent += count;
2328 len -= count;
2329
2330 /* Continuation fragments (no L2CAP header) */
2331 frag = &skb_shinfo(skb)->frag_list;
2332 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002333 struct sk_buff *tmp;
2334
Linus Torvalds1da177e2005-04-16 15:20:36 -07002335 count = min_t(unsigned int, conn->mtu, len);
2336
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002337 tmp = chan->ops->alloc_skb(chan, count,
2338 msg->msg_flags & MSG_DONTWAIT);
2339 if (IS_ERR(tmp))
2340 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002341
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002342 *frag = tmp;
2343
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002344 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2345 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002346
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002347 (*frag)->priority = skb->priority;
2348
Linus Torvalds1da177e2005-04-16 15:20:36 -07002349 sent += count;
2350 len -= count;
2351
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002352 skb->len += (*frag)->len;
2353 skb->data_len += (*frag)->len;
2354
Linus Torvalds1da177e2005-04-16 15:20:36 -07002355 frag = &(*frag)->next;
2356 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002357
2358 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002359}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002360
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002361static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002362 struct msghdr *msg, size_t len,
2363 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002364{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002365 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002366 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002367 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002368 struct l2cap_hdr *lh;
2369
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002370 BT_DBG("chan %p psm 0x%2.2x len %zu priority %u", chan,
2371 __le16_to_cpu(chan->psm), len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002372
2373 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002374
2375 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002376 msg->msg_flags & MSG_DONTWAIT);
2377 if (IS_ERR(skb))
2378 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002379
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002380 skb->priority = priority;
2381
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002382 /* Create L2CAP header */
2383 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002384 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002385 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002386 put_unaligned(chan->psm, (__le16 *) skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002387
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002388 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002389 if (unlikely(err < 0)) {
2390 kfree_skb(skb);
2391 return ERR_PTR(err);
2392 }
2393 return skb;
2394}
2395
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002396static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002397 struct msghdr *msg, size_t len,
2398 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002399{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002400 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002401 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002402 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002403 struct l2cap_hdr *lh;
2404
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002405 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002406
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002407 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002408
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002409 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002410 msg->msg_flags & MSG_DONTWAIT);
2411 if (IS_ERR(skb))
2412 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002413
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002414 skb->priority = priority;
2415
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002416 /* Create L2CAP header */
2417 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002418 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002419 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002420
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002421 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002422 if (unlikely(err < 0)) {
2423 kfree_skb(skb);
2424 return ERR_PTR(err);
2425 }
2426 return skb;
2427}
2428
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002429static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002430 struct msghdr *msg, size_t len,
2431 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002432{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002433 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002434 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002435 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002436 struct l2cap_hdr *lh;
2437
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002438 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002439
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002440 if (!conn)
2441 return ERR_PTR(-ENOTCONN);
2442
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002443 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002444
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002445 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002446 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002447
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002448 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002449 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002450
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002451 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002452
2453 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002454 msg->msg_flags & MSG_DONTWAIT);
2455 if (IS_ERR(skb))
2456 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002457
2458 /* Create L2CAP header */
2459 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002460 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002461 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002462
Mat Martineau18a48e72012-05-17 20:53:34 -07002463 /* Control header is populated later */
2464 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2465 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2466 else
2467 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002468
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002469 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002470 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002471
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002472 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002473 if (unlikely(err < 0)) {
2474 kfree_skb(skb);
2475 return ERR_PTR(err);
2476 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002477
Mat Martineau18a48e72012-05-17 20:53:34 -07002478 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002479 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002480 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002481}
2482
Mat Martineau94122bb2012-05-02 09:42:02 -07002483static int l2cap_segment_sdu(struct l2cap_chan *chan,
2484 struct sk_buff_head *seg_queue,
2485 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002486{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002487 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002488 u16 sdu_len;
2489 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002490 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002491
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002492 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002493
Mat Martineau94122bb2012-05-02 09:42:02 -07002494 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2495 * so fragmented skbs are not used. The HCI layer's handling
2496 * of fragmented skbs is not compatible with ERTM's queueing.
2497 */
2498
2499 /* PDU size is derived from the HCI MTU */
2500 pdu_len = chan->conn->mtu;
2501
Mat Martineaua5495742012-10-23 15:24:21 -07002502 /* Constrain PDU size for BR/EDR connections */
2503 if (!chan->hs_hcon)
2504 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002505
2506 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002507 if (chan->fcs)
2508 pdu_len -= L2CAP_FCS_SIZE;
2509
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002510 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002511
2512 /* Remote device may have requested smaller PDUs */
2513 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2514
2515 if (len <= pdu_len) {
2516 sar = L2CAP_SAR_UNSEGMENTED;
2517 sdu_len = 0;
2518 pdu_len = len;
2519 } else {
2520 sar = L2CAP_SAR_START;
2521 sdu_len = len;
2522 pdu_len -= L2CAP_SDULEN_SIZE;
2523 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002524
2525 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002526 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002527
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002528 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002529 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002530 return PTR_ERR(skb);
2531 }
2532
Mat Martineau94122bb2012-05-02 09:42:02 -07002533 bt_cb(skb)->control.sar = sar;
2534 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002535
Mat Martineau94122bb2012-05-02 09:42:02 -07002536 len -= pdu_len;
2537 if (sdu_len) {
2538 sdu_len = 0;
2539 pdu_len += L2CAP_SDULEN_SIZE;
2540 }
2541
2542 if (len <= pdu_len) {
2543 sar = L2CAP_SAR_END;
2544 pdu_len = len;
2545 } else {
2546 sar = L2CAP_SAR_CONTINUE;
2547 }
2548 }
2549
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002550 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002551}
2552
Johan Hedberg177f8f22013-05-31 17:54:51 +03002553static struct sk_buff *l2cap_create_le_flowctl_pdu(struct l2cap_chan *chan,
2554 struct msghdr *msg,
2555 size_t len, u16 sdulen)
2556{
2557 struct l2cap_conn *conn = chan->conn;
2558 struct sk_buff *skb;
2559 int err, count, hlen;
2560 struct l2cap_hdr *lh;
2561
2562 BT_DBG("chan %p len %zu", chan, len);
2563
2564 if (!conn)
2565 return ERR_PTR(-ENOTCONN);
2566
2567 hlen = L2CAP_HDR_SIZE;
2568
2569 if (sdulen)
2570 hlen += L2CAP_SDULEN_SIZE;
2571
2572 count = min_t(unsigned int, (conn->mtu - hlen), len);
2573
2574 skb = chan->ops->alloc_skb(chan, count + hlen,
2575 msg->msg_flags & MSG_DONTWAIT);
2576 if (IS_ERR(skb))
2577 return skb;
2578
2579 /* Create L2CAP header */
2580 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
2581 lh->cid = cpu_to_le16(chan->dcid);
2582 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
2583
2584 if (sdulen)
2585 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
2586
2587 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
2588 if (unlikely(err < 0)) {
2589 kfree_skb(skb);
2590 return ERR_PTR(err);
2591 }
2592
2593 return skb;
2594}
2595
2596static int l2cap_segment_le_sdu(struct l2cap_chan *chan,
2597 struct sk_buff_head *seg_queue,
2598 struct msghdr *msg, size_t len)
2599{
2600 struct sk_buff *skb;
2601 size_t pdu_len;
2602 u16 sdu_len;
2603
2604 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
2605
2606 pdu_len = chan->conn->mtu - L2CAP_HDR_SIZE;
2607
2608 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2609
2610 sdu_len = len;
2611 pdu_len -= L2CAP_SDULEN_SIZE;
2612
2613 while (len > 0) {
2614 if (len <= pdu_len)
2615 pdu_len = len;
2616
2617 skb = l2cap_create_le_flowctl_pdu(chan, msg, pdu_len, sdu_len);
2618 if (IS_ERR(skb)) {
2619 __skb_queue_purge(seg_queue);
2620 return PTR_ERR(skb);
2621 }
2622
2623 __skb_queue_tail(seg_queue, skb);
2624
2625 len -= pdu_len;
2626
2627 if (sdu_len) {
2628 sdu_len = 0;
2629 pdu_len += L2CAP_SDULEN_SIZE;
2630 }
2631 }
2632
2633 return 0;
2634}
2635
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002636int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002637 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002638{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002639 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002640 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002641 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002642
Seung-Woo Kim31e8ce82013-11-05 18:46:33 +09002643 if (!chan->conn)
2644 return -ENOTCONN;
2645
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002646 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002647 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002648 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002649 if (IS_ERR(skb))
2650 return PTR_ERR(skb);
2651
2652 l2cap_do_send(chan, skb);
2653 return len;
2654 }
2655
2656 switch (chan->mode) {
Johan Hedberg38319712013-05-17 12:49:23 +03002657 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedberg177f8f22013-05-31 17:54:51 +03002658 /* Check outgoing MTU */
2659 if (len > chan->omtu)
2660 return -EMSGSIZE;
2661
Johan Hedbergfad5fc892013-12-05 09:45:01 +02002662 if (!chan->tx_credits)
2663 return -EAGAIN;
2664
Johan Hedberg177f8f22013-05-31 17:54:51 +03002665 __skb_queue_head_init(&seg_queue);
2666
2667 err = l2cap_segment_le_sdu(chan, &seg_queue, msg, len);
2668
2669 if (chan->state != BT_CONNECTED) {
2670 __skb_queue_purge(&seg_queue);
2671 err = -ENOTCONN;
2672 }
2673
2674 if (err)
2675 return err;
2676
2677 skb_queue_splice_tail_init(&seg_queue, &chan->tx_q);
2678
2679 while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
2680 l2cap_do_send(chan, skb_dequeue(&chan->tx_q));
2681 chan->tx_credits--;
2682 }
2683
2684 if (!chan->tx_credits)
2685 chan->ops->suspend(chan);
2686
2687 err = len;
2688
2689 break;
2690
Johan Hedbergfad5fc892013-12-05 09:45:01 +02002691 case L2CAP_MODE_BASIC:
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002692 /* Check outgoing MTU */
2693 if (len > chan->omtu)
2694 return -EMSGSIZE;
2695
2696 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002697 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002698 if (IS_ERR(skb))
2699 return PTR_ERR(skb);
2700
2701 l2cap_do_send(chan, skb);
2702 err = len;
2703 break;
2704
2705 case L2CAP_MODE_ERTM:
2706 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002707 /* Check outgoing MTU */
2708 if (len > chan->omtu) {
2709 err = -EMSGSIZE;
2710 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002711 }
2712
Mat Martineau94122bb2012-05-02 09:42:02 -07002713 __skb_queue_head_init(&seg_queue);
2714
2715 /* Do segmentation before calling in to the state machine,
2716 * since it's possible to block while waiting for memory
2717 * allocation.
2718 */
2719 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2720
2721 /* The channel could have been closed while segmenting,
2722 * check that it is still connected.
2723 */
2724 if (chan->state != BT_CONNECTED) {
2725 __skb_queue_purge(&seg_queue);
2726 err = -ENOTCONN;
2727 }
2728
2729 if (err)
2730 break;
2731
Mat Martineau37339372012-05-17 20:53:33 -07002732 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002733 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002734 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002735 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002736
Gustavo Padovand6603662012-05-21 13:58:22 -03002737 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002738
Mat Martineau94122bb2012-05-02 09:42:02 -07002739 /* If the skbs were not queued for sending, they'll still be in
2740 * seg_queue and need to be purged.
2741 */
2742 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002743 break;
2744
2745 default:
2746 BT_DBG("bad state %1.1x", chan->mode);
2747 err = -EBADFD;
2748 }
2749
2750 return err;
2751}
2752
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002753static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2754{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002755 struct l2cap_ctrl control;
2756 u16 seq;
2757
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002758 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002759
2760 memset(&control, 0, sizeof(control));
2761 control.sframe = 1;
2762 control.super = L2CAP_SUPER_SREJ;
2763
2764 for (seq = chan->expected_tx_seq; seq != txseq;
2765 seq = __next_seq(chan, seq)) {
2766 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2767 control.reqseq = seq;
2768 l2cap_send_sframe(chan, &control);
2769 l2cap_seq_list_append(&chan->srej_list, seq);
2770 }
2771 }
2772
2773 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002774}
2775
2776static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2777{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002778 struct l2cap_ctrl control;
2779
2780 BT_DBG("chan %p", chan);
2781
2782 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2783 return;
2784
2785 memset(&control, 0, sizeof(control));
2786 control.sframe = 1;
2787 control.super = L2CAP_SUPER_SREJ;
2788 control.reqseq = chan->srej_list.tail;
2789 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002790}
2791
2792static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2793{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002794 struct l2cap_ctrl control;
2795 u16 initial_head;
2796 u16 seq;
2797
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002798 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002799
2800 memset(&control, 0, sizeof(control));
2801 control.sframe = 1;
2802 control.super = L2CAP_SUPER_SREJ;
2803
2804 /* Capture initial list head to allow only one pass through the list. */
2805 initial_head = chan->srej_list.head;
2806
2807 do {
2808 seq = l2cap_seq_list_pop(&chan->srej_list);
2809 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2810 break;
2811
2812 control.reqseq = seq;
2813 l2cap_send_sframe(chan, &control);
2814 l2cap_seq_list_append(&chan->srej_list, seq);
2815 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002816}
2817
Mat Martineau608bcc62012-05-17 20:53:32 -07002818static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2819{
2820 struct sk_buff *acked_skb;
2821 u16 ackseq;
2822
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002823 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002824
2825 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2826 return;
2827
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002828 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002829 chan->expected_ack_seq, chan->unacked_frames);
2830
2831 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2832 ackseq = __next_seq(chan, ackseq)) {
2833
2834 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2835 if (acked_skb) {
2836 skb_unlink(acked_skb, &chan->tx_q);
2837 kfree_skb(acked_skb);
2838 chan->unacked_frames--;
2839 }
2840 }
2841
2842 chan->expected_ack_seq = reqseq;
2843
2844 if (chan->unacked_frames == 0)
2845 __clear_retrans_timer(chan);
2846
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002847 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002848}
2849
2850static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2851{
2852 BT_DBG("chan %p", chan);
2853
2854 chan->expected_tx_seq = chan->buffer_seq;
2855 l2cap_seq_list_clear(&chan->srej_list);
2856 skb_queue_purge(&chan->srej_q);
2857 chan->rx_state = L2CAP_RX_STATE_RECV;
2858}
2859
Gustavo Padovand6603662012-05-21 13:58:22 -03002860static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2861 struct l2cap_ctrl *control,
2862 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002863{
Mat Martineau608bcc62012-05-17 20:53:32 -07002864 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2865 event);
2866
2867 switch (event) {
2868 case L2CAP_EV_DATA_REQUEST:
2869 if (chan->tx_send_head == NULL)
2870 chan->tx_send_head = skb_peek(skbs);
2871
2872 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2873 l2cap_ertm_send(chan);
2874 break;
2875 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2876 BT_DBG("Enter LOCAL_BUSY");
2877 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2878
2879 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2880 /* The SREJ_SENT state must be aborted if we are to
2881 * enter the LOCAL_BUSY state.
2882 */
2883 l2cap_abort_rx_srej_sent(chan);
2884 }
2885
2886 l2cap_send_ack(chan);
2887
2888 break;
2889 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2890 BT_DBG("Exit LOCAL_BUSY");
2891 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2892
2893 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2894 struct l2cap_ctrl local_control;
2895
2896 memset(&local_control, 0, sizeof(local_control));
2897 local_control.sframe = 1;
2898 local_control.super = L2CAP_SUPER_RR;
2899 local_control.poll = 1;
2900 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002901 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002902
2903 chan->retry_count = 1;
2904 __set_monitor_timer(chan);
2905 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2906 }
2907 break;
2908 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2909 l2cap_process_reqseq(chan, control->reqseq);
2910 break;
2911 case L2CAP_EV_EXPLICIT_POLL:
2912 l2cap_send_rr_or_rnr(chan, 1);
2913 chan->retry_count = 1;
2914 __set_monitor_timer(chan);
2915 __clear_ack_timer(chan);
2916 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2917 break;
2918 case L2CAP_EV_RETRANS_TO:
2919 l2cap_send_rr_or_rnr(chan, 1);
2920 chan->retry_count = 1;
2921 __set_monitor_timer(chan);
2922 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2923 break;
2924 case L2CAP_EV_RECV_FBIT:
2925 /* Nothing to process */
2926 break;
2927 default:
2928 break;
2929 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002930}
2931
Gustavo Padovand6603662012-05-21 13:58:22 -03002932static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2933 struct l2cap_ctrl *control,
2934 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002935{
Mat Martineau608bcc62012-05-17 20:53:32 -07002936 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2937 event);
2938
2939 switch (event) {
2940 case L2CAP_EV_DATA_REQUEST:
2941 if (chan->tx_send_head == NULL)
2942 chan->tx_send_head = skb_peek(skbs);
2943 /* Queue data, but don't send. */
2944 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2945 break;
2946 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2947 BT_DBG("Enter LOCAL_BUSY");
2948 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2949
2950 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2951 /* The SREJ_SENT state must be aborted if we are to
2952 * enter the LOCAL_BUSY state.
2953 */
2954 l2cap_abort_rx_srej_sent(chan);
2955 }
2956
2957 l2cap_send_ack(chan);
2958
2959 break;
2960 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2961 BT_DBG("Exit LOCAL_BUSY");
2962 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2963
2964 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2965 struct l2cap_ctrl local_control;
2966 memset(&local_control, 0, sizeof(local_control));
2967 local_control.sframe = 1;
2968 local_control.super = L2CAP_SUPER_RR;
2969 local_control.poll = 1;
2970 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002971 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002972
2973 chan->retry_count = 1;
2974 __set_monitor_timer(chan);
2975 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2976 }
2977 break;
2978 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2979 l2cap_process_reqseq(chan, control->reqseq);
2980
2981 /* Fall through */
2982
2983 case L2CAP_EV_RECV_FBIT:
2984 if (control && control->final) {
2985 __clear_monitor_timer(chan);
2986 if (chan->unacked_frames > 0)
2987 __set_retrans_timer(chan);
2988 chan->retry_count = 0;
2989 chan->tx_state = L2CAP_TX_STATE_XMIT;
2990 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2991 }
2992 break;
2993 case L2CAP_EV_EXPLICIT_POLL:
2994 /* Ignore */
2995 break;
2996 case L2CAP_EV_MONITOR_TO:
2997 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2998 l2cap_send_rr_or_rnr(chan, 1);
2999 __set_monitor_timer(chan);
3000 chan->retry_count++;
3001 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02003002 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07003003 }
3004 break;
3005 default:
3006 break;
3007 }
Mat Martineau608bcc62012-05-17 20:53:32 -07003008}
3009
Gustavo Padovand6603662012-05-21 13:58:22 -03003010static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
3011 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07003012{
Mat Martineau608bcc62012-05-17 20:53:32 -07003013 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
3014 chan, control, skbs, event, chan->tx_state);
3015
3016 switch (chan->tx_state) {
3017 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03003018 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07003019 break;
3020 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03003021 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07003022 break;
3023 default:
3024 /* Ignore event */
3025 break;
3026 }
Mat Martineau608bcc62012-05-17 20:53:32 -07003027}
3028
Mat Martineau4b51dae92012-05-17 20:53:37 -07003029static void l2cap_pass_to_tx(struct l2cap_chan *chan,
3030 struct l2cap_ctrl *control)
3031{
3032 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03003033 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07003034}
3035
Mat Martineauf80842a2012-05-17 20:53:46 -07003036static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
3037 struct l2cap_ctrl *control)
3038{
3039 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03003040 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07003041}
3042
Linus Torvalds1da177e2005-04-16 15:20:36 -07003043/* Copy frame to all raw sockets on that connection */
3044static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
3045{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003046 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003047 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003048
3049 BT_DBG("conn %p", conn);
3050
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003051 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02003052
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003053 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03003054 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003055 continue;
3056
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02003057 /* Don't send frame to the channel it came from */
3058 if (bt_cb(skb)->chan == chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003059 continue;
Gustavo Padovan7f5396a2013-10-21 18:22:25 -02003060
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03003061 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03003062 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003063 continue;
Gustavo Padovan80b98022012-05-27 22:27:51 -03003064 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003065 kfree_skb(nskb);
3066 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02003067
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003068 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003069}
3070
3071/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003072static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
3073 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003074{
3075 struct sk_buff *skb, **frag;
3076 struct l2cap_cmd_hdr *cmd;
3077 struct l2cap_hdr *lh;
3078 int len, count;
3079
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003080 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
3081 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003082
Anderson Lizardo300b9622013-06-02 16:30:40 -04003083 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
3084 return NULL;
3085
Linus Torvalds1da177e2005-04-16 15:20:36 -07003086 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
3087 count = min_t(unsigned int, conn->mtu, len);
3088
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03003089 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003090 if (!skb)
3091 return NULL;
3092
3093 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003094 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02003095
3096 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003097 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02003098 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003099 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003100
3101 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
3102 cmd->code = code;
3103 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003104 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003105
3106 if (dlen) {
3107 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
3108 memcpy(skb_put(skb, count), data, count);
3109 data += count;
3110 }
3111
3112 len -= skb->len;
3113
3114 /* Continuation fragments (no L2CAP header) */
3115 frag = &skb_shinfo(skb)->frag_list;
3116 while (len) {
3117 count = min_t(unsigned int, conn->mtu, len);
3118
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03003119 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003120 if (!*frag)
3121 goto fail;
3122
3123 memcpy(skb_put(*frag, count), data, count);
3124
3125 len -= count;
3126 data += count;
3127
3128 frag = &(*frag)->next;
3129 }
3130
3131 return skb;
3132
3133fail:
3134 kfree_skb(skb);
3135 return NULL;
3136}
3137
Gustavo Padovan2d792812012-10-06 10:07:01 +01003138static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
3139 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003140{
3141 struct l2cap_conf_opt *opt = *ptr;
3142 int len;
3143
3144 len = L2CAP_CONF_OPT_SIZE + opt->len;
3145 *ptr += len;
3146
3147 *type = opt->type;
3148 *olen = opt->len;
3149
3150 switch (opt->len) {
3151 case 1:
3152 *val = *((u8 *) opt->val);
3153 break;
3154
3155 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04003156 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003157 break;
3158
3159 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04003160 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003161 break;
3162
3163 default:
3164 *val = (unsigned long) opt->val;
3165 break;
3166 }
3167
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003168 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003169 return len;
3170}
3171
Linus Torvalds1da177e2005-04-16 15:20:36 -07003172static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
3173{
3174 struct l2cap_conf_opt *opt = *ptr;
3175
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03003176 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003177
3178 opt->type = type;
3179 opt->len = len;
3180
3181 switch (len) {
3182 case 1:
3183 *((u8 *) opt->val) = val;
3184 break;
3185
3186 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003187 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003188 break;
3189
3190 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02003191 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003192 break;
3193
3194 default:
3195 memcpy(opt->val, (void *) val, len);
3196 break;
3197 }
3198
3199 *ptr += L2CAP_CONF_OPT_SIZE + len;
3200}
3201
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003202static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
3203{
3204 struct l2cap_conf_efs efs;
3205
Szymon Janc1ec918c2011-11-16 09:32:21 +01003206 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003207 case L2CAP_MODE_ERTM:
3208 efs.id = chan->local_id;
3209 efs.stype = chan->local_stype;
3210 efs.msdu = cpu_to_le16(chan->local_msdu);
3211 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003212 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003213 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003214 break;
3215
3216 case L2CAP_MODE_STREAMING:
3217 efs.id = 1;
3218 efs.stype = L2CAP_SERV_BESTEFFORT;
3219 efs.msdu = cpu_to_le16(chan->local_msdu);
3220 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
3221 efs.acc_lat = 0;
3222 efs.flush_to = 0;
3223 break;
3224
3225 default:
3226 return;
3227 }
3228
3229 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003230 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003231}
3232
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003233static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003234{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003235 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003236 ack_timer.work);
3237 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003238
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003239 BT_DBG("chan %p", chan);
3240
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003241 l2cap_chan_lock(chan);
3242
Mat Martineau03625202012-05-17 20:53:51 -07003243 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3244 chan->last_acked_seq);
3245
3246 if (frames_to_ack)
3247 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003248
3249 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003250 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003251}
3252
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003253int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003254{
Mat Martineau3c588192012-04-11 10:48:42 -07003255 int err;
3256
Mat Martineau105bdf92012-04-27 16:50:48 -07003257 chan->next_tx_seq = 0;
3258 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003259 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003260 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003261 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003262 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003263 chan->last_acked_seq = 0;
3264 chan->sdu = NULL;
3265 chan->sdu_last_frag = NULL;
3266 chan->sdu_len = 0;
3267
Mat Martineaud34c34f2012-05-14 14:49:27 -07003268 skb_queue_head_init(&chan->tx_q);
3269
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003270 chan->local_amp_id = AMP_ID_BREDR;
3271 chan->move_id = AMP_ID_BREDR;
Mat Martineau08333282012-10-23 15:24:06 -07003272 chan->move_state = L2CAP_MOVE_STABLE;
3273 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3274
Mat Martineau105bdf92012-04-27 16:50:48 -07003275 if (chan->mode != L2CAP_MODE_ERTM)
3276 return 0;
3277
3278 chan->rx_state = L2CAP_RX_STATE_RECV;
3279 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003280
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003281 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3282 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3283 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003284
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003285 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003286
Mat Martineau3c588192012-04-11 10:48:42 -07003287 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3288 if (err < 0)
3289 return err;
3290
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003291 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3292 if (err < 0)
3293 l2cap_seq_list_free(&chan->srej_list);
3294
3295 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003296}
3297
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003298static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3299{
3300 switch (mode) {
3301 case L2CAP_MODE_STREAMING:
3302 case L2CAP_MODE_ERTM:
3303 if (l2cap_mode_supported(mode, remote_feat_mask))
3304 return mode;
3305 /* fall through */
3306 default:
3307 return L2CAP_MODE_BASIC;
3308 }
3309}
3310
Marcel Holtmann848566b2013-10-01 22:59:22 -07003311static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003312{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003313 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003314}
3315
Marcel Holtmann848566b2013-10-01 22:59:22 -07003316static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003317{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003318 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003319}
3320
Mat Martineau36c86c82012-10-23 15:24:20 -07003321static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3322 struct l2cap_conf_rfc *rfc)
3323{
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003324 if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) {
Mat Martineau36c86c82012-10-23 15:24:20 -07003325 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3326
3327 /* Class 1 devices have must have ERTM timeouts
3328 * exceeding the Link Supervision Timeout. The
3329 * default Link Supervision Timeout for AMP
3330 * controllers is 10 seconds.
3331 *
3332 * Class 1 devices use 0xffffffff for their
3333 * best-effort flush timeout, so the clamping logic
3334 * will result in a timeout that meets the above
3335 * requirement. ERTM timeouts are 16-bit values, so
3336 * the maximum timeout is 65.535 seconds.
3337 */
3338
3339 /* Convert timeout to milliseconds and round */
3340 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3341
3342 /* This is the recommended formula for class 2 devices
3343 * that start ERTM timers when packets are sent to the
3344 * controller.
3345 */
3346 ertm_to = 3 * ertm_to + 500;
3347
3348 if (ertm_to > 0xffff)
3349 ertm_to = 0xffff;
3350
3351 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3352 rfc->monitor_timeout = rfc->retrans_timeout;
3353 } else {
3354 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3355 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3356 }
3357}
3358
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003359static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3360{
3361 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Marcel Holtmann848566b2013-10-01 22:59:22 -07003362 __l2cap_ews_supported(chan->conn)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003363 /* use extended control field */
3364 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003365 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3366 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003367 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003368 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003369 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3370 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003371 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003372}
3373
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003374static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003375{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003376 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003377 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003378 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003379 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003380
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003381 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003382
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003383 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003384 goto done;
3385
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003386 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003387 case L2CAP_MODE_STREAMING:
3388 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003389 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003390 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003391
Marcel Holtmann848566b2013-10-01 22:59:22 -07003392 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003393 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3394
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003395 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003396 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003397 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003398 break;
3399 }
3400
3401done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003402 if (chan->imtu != L2CAP_DEFAULT_MTU)
3403 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003404
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003405 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003406 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003407 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003408 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003409 break;
3410
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003411 rfc.mode = L2CAP_MODE_BASIC;
3412 rfc.txwin_size = 0;
3413 rfc.max_transmit = 0;
3414 rfc.retrans_timeout = 0;
3415 rfc.monitor_timeout = 0;
3416 rfc.max_pdu_size = 0;
3417
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003418 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003419 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003420 break;
3421
3422 case L2CAP_MODE_ERTM:
3423 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003424 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003425
3426 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003427
3428 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003429 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3430 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003431 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003432
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003433 l2cap_txwin_setup(chan);
3434
3435 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003436 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003437
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003438 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003439 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003440
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003441 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3442 l2cap_add_opt_efs(&ptr, chan);
3443
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003444 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3445 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003446 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003447
3448 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3449 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003450 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003451 chan->fcs = L2CAP_FCS_NONE;
3452 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3453 chan->fcs);
3454 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003455 break;
3456
3457 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003458 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003459 rfc.mode = L2CAP_MODE_STREAMING;
3460 rfc.txwin_size = 0;
3461 rfc.max_transmit = 0;
3462 rfc.retrans_timeout = 0;
3463 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003464
3465 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003466 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3467 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003468 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003469
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003470 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003471 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003472
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003473 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3474 l2cap_add_opt_efs(&ptr, chan);
3475
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003476 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3477 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003478 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003479 chan->fcs = L2CAP_FCS_NONE;
3480 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3481 chan->fcs);
3482 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003483 break;
3484 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003485
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003486 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003487 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003488
3489 return ptr - data;
3490}
3491
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003492static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003493{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003494 struct l2cap_conf_rsp *rsp = data;
3495 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003496 void *req = chan->conf_req;
3497 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003498 int type, hint, olen;
3499 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003500 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003501 struct l2cap_conf_efs efs;
3502 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003503 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003504 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003505 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003506
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003507 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003508
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003509 while (len >= L2CAP_CONF_OPT_SIZE) {
3510 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003511
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003512 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003513 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003514
3515 switch (type) {
3516 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003517 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003518 break;
3519
3520 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003521 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003522 break;
3523
3524 case L2CAP_CONF_QOS:
3525 break;
3526
Marcel Holtmann6464f352007-10-20 13:39:51 +02003527 case L2CAP_CONF_RFC:
3528 if (olen == sizeof(rfc))
3529 memcpy(&rfc, (void *) val, olen);
3530 break;
3531
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003532 case L2CAP_CONF_FCS:
3533 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003534 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003535 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003536
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003537 case L2CAP_CONF_EFS:
3538 remote_efs = 1;
3539 if (olen == sizeof(efs))
3540 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003541 break;
3542
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003543 case L2CAP_CONF_EWS:
Marcel Holtmann848566b2013-10-01 22:59:22 -07003544 if (!chan->conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003545 return -ECONNREFUSED;
3546
3547 set_bit(FLAG_EXT_CTRL, &chan->flags);
3548 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003549 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003550 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003551 break;
3552
3553 default:
3554 if (hint)
3555 break;
3556
3557 result = L2CAP_CONF_UNKNOWN;
3558 *((u8 *) ptr++) = type;
3559 break;
3560 }
3561 }
3562
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003563 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003564 goto done;
3565
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003566 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003567 case L2CAP_MODE_STREAMING:
3568 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003569 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003570 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003571 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003572 break;
3573 }
3574
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003575 if (remote_efs) {
Marcel Holtmann848566b2013-10-01 22:59:22 -07003576 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003577 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3578 else
3579 return -ECONNREFUSED;
3580 }
3581
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003582 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003583 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003584
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003585 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003586 }
3587
3588done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003589 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003590 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003591 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003592
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003593 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003594 return -ECONNREFUSED;
3595
Gustavo Padovan2d792812012-10-06 10:07:01 +01003596 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3597 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003598 }
3599
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003600 if (result == L2CAP_CONF_SUCCESS) {
3601 /* Configure output options and let the other side know
3602 * which ones we don't like. */
3603
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003604 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3605 result = L2CAP_CONF_UNACCEPT;
3606 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003607 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003608 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003609 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003610 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003611
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003612 if (remote_efs) {
3613 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003614 efs.stype != L2CAP_SERV_NOTRAFIC &&
3615 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003616
3617 result = L2CAP_CONF_UNACCEPT;
3618
3619 if (chan->num_conf_req >= 1)
3620 return -ECONNREFUSED;
3621
3622 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003623 sizeof(efs),
3624 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003625 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003626 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003627 result = L2CAP_CONF_PENDING;
3628 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003629 }
3630 }
3631
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003632 switch (rfc.mode) {
3633 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003634 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003635 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003636 break;
3637
3638 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003639 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3640 chan->remote_tx_win = rfc.txwin_size;
3641 else
3642 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3643
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003644 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003645
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003646 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003647 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3648 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003649 rfc.max_pdu_size = cpu_to_le16(size);
3650 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003651
Mat Martineau36c86c82012-10-23 15:24:20 -07003652 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003653
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003654 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003655
3656 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003657 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003658
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003659 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3660 chan->remote_id = efs.id;
3661 chan->remote_stype = efs.stype;
3662 chan->remote_msdu = le16_to_cpu(efs.msdu);
3663 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003664 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003665 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003666 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003667 chan->remote_sdu_itime =
3668 le32_to_cpu(efs.sdu_itime);
3669 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003670 sizeof(efs),
3671 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003672 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003673 break;
3674
3675 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003676 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003677 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3678 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003679 rfc.max_pdu_size = cpu_to_le16(size);
3680 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003681
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003682 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003683
Gustavo Padovan2d792812012-10-06 10:07:01 +01003684 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3685 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003686
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003687 break;
3688
3689 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003690 result = L2CAP_CONF_UNACCEPT;
3691
3692 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003693 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003694 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003695
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003696 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003697 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003698 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003699 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003700 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003701 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003702
3703 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003704}
3705
Gustavo Padovan2d792812012-10-06 10:07:01 +01003706static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3707 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003708{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003709 struct l2cap_conf_req *req = data;
3710 void *ptr = req->data;
3711 int type, olen;
3712 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003713 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003714 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003715
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003716 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003717
3718 while (len >= L2CAP_CONF_OPT_SIZE) {
3719 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3720
3721 switch (type) {
3722 case L2CAP_CONF_MTU:
3723 if (val < L2CAP_DEFAULT_MIN_MTU) {
3724 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003725 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003726 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003727 chan->imtu = val;
3728 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003729 break;
3730
3731 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003732 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003733 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003734 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003735 break;
3736
3737 case L2CAP_CONF_RFC:
3738 if (olen == sizeof(rfc))
3739 memcpy(&rfc, (void *)val, olen);
3740
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003741 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003742 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003743 return -ECONNREFUSED;
3744
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003745 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003746
3747 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003748 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003749 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003750
3751 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003752 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003753 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003754 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003755 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003756
3757 case L2CAP_CONF_EFS:
3758 if (olen == sizeof(efs))
3759 memcpy(&efs, (void *)val, olen);
3760
3761 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003762 efs.stype != L2CAP_SERV_NOTRAFIC &&
3763 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003764 return -ECONNREFUSED;
3765
Gustavo Padovan2d792812012-10-06 10:07:01 +01003766 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3767 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003768 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003769
3770 case L2CAP_CONF_FCS:
3771 if (*result == L2CAP_CONF_PENDING)
3772 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003773 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003774 &chan->conf_state);
3775 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003776 }
3777 }
3778
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003779 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003780 return -ECONNREFUSED;
3781
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003782 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003783
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003784 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003785 switch (rfc.mode) {
3786 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003787 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3788 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3789 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003790 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3791 chan->ack_win = min_t(u16, chan->ack_win,
3792 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003793
3794 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3795 chan->local_msdu = le16_to_cpu(efs.msdu);
3796 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003797 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003798 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3799 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003800 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003801 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003802 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003803
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003804 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003805 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003806 }
3807 }
3808
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003809 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003810 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003811
3812 return ptr - data;
3813}
3814
Gustavo Padovan2d792812012-10-06 10:07:01 +01003815static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3816 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003817{
3818 struct l2cap_conf_rsp *rsp = data;
3819 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003820
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003821 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003822
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003823 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003824 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003825 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003826
3827 return ptr - data;
3828}
3829
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03003830void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan)
3831{
3832 struct l2cap_le_conn_rsp rsp;
3833 struct l2cap_conn *conn = chan->conn;
3834
3835 BT_DBG("chan %p", chan);
3836
3837 rsp.dcid = cpu_to_le16(chan->scid);
3838 rsp.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +02003839 rsp.mps = cpu_to_le16(chan->mps);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03003840 rsp.credits = cpu_to_le16(chan->rx_credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03003841 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3842
3843 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
3844 &rsp);
3845}
3846
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003847void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003848{
3849 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003850 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003851 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003852 u8 rsp_code;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003853
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003854 rsp.scid = cpu_to_le16(chan->dcid);
3855 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003856 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3857 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003858
3859 if (chan->hs_hcon)
3860 rsp_code = L2CAP_CREATE_CHAN_RSP;
3861 else
3862 rsp_code = L2CAP_CONN_RSP;
3863
3864 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3865
3866 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003867
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003868 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003869 return;
3870
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003871 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003872 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003873 chan->num_conf_req++;
3874}
3875
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003876static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003877{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003878 int type, olen;
3879 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003880 /* Use sane default values in case a misbehaving remote device
3881 * did not send an RFC or extended window size option.
3882 */
3883 u16 txwin_ext = chan->ack_win;
3884 struct l2cap_conf_rfc rfc = {
3885 .mode = chan->mode,
3886 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3887 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3888 .max_pdu_size = cpu_to_le16(chan->imtu),
3889 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3890 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003891
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003892 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003893
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003894 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003895 return;
3896
3897 while (len >= L2CAP_CONF_OPT_SIZE) {
3898 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3899
Mat Martineauc20f8e32012-07-10 05:47:07 -07003900 switch (type) {
3901 case L2CAP_CONF_RFC:
3902 if (olen == sizeof(rfc))
3903 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003904 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003905 case L2CAP_CONF_EWS:
3906 txwin_ext = val;
3907 break;
3908 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003909 }
3910
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003911 switch (rfc.mode) {
3912 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003913 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3914 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003915 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3916 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3917 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3918 else
3919 chan->ack_win = min_t(u16, chan->ack_win,
3920 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003921 break;
3922 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003923 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003924 }
3925}
3926
Gustavo Padovan2d792812012-10-06 10:07:01 +01003927static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003928 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3929 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003930{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003931 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003932
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003933 if (cmd_len < sizeof(*rej))
3934 return -EPROTO;
3935
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003936 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003937 return 0;
3938
3939 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003940 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003941 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003942
3943 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003944 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003945
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003946 l2cap_conn_start(conn);
3947 }
3948
3949 return 0;
3950}
3951
Mat Martineau17009152012-10-23 15:24:07 -07003952static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3953 struct l2cap_cmd_hdr *cmd,
3954 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003955{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003956 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3957 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003958 struct l2cap_chan *chan = NULL, *pchan;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003959 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003960
3961 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003962 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003963
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003964 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003965
3966 /* Check if we have socket listening on psm */
Marcel Holtmann6f59b902013-10-13 05:24:01 -07003967 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
Johan Hedbergbf20fd42013-05-14 13:23:13 +03003968 &conn->hcon->dst, ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003969 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003970 result = L2CAP_CR_BAD_PSM;
3971 goto sendresp;
3972 }
3973
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003974 mutex_lock(&conn->chan_lock);
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02003975 l2cap_chan_lock(pchan);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003976
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003977 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003978 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003979 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003980 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003981 result = L2CAP_CR_SEC_BLOCK;
3982 goto response;
3983 }
3984
Linus Torvalds1da177e2005-04-16 15:20:36 -07003985 result = L2CAP_CR_NO_MEM;
3986
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003987 /* Check if we already have channel with that dcid */
3988 if (__l2cap_get_chan_by_dcid(conn, scid))
3989 goto response;
3990
Gustavo Padovan80b98022012-05-27 22:27:51 -03003991 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003992 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003993 goto response;
3994
Syam Sidhardhan330b6c12013-08-06 01:59:12 +09003995 /* For certain devices (ex: HID mouse), support for authentication,
3996 * pairing and bonding is optional. For such devices, inorder to avoid
3997 * the ACL alive for too long after L2CAP disconnection, reset the ACL
3998 * disc_timeout back to HCI_DISCONN_TIMEOUT during L2CAP connect.
3999 */
4000 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
4001
Marcel Holtmann7eafc592013-10-13 08:12:47 -07004002 bacpy(&chan->src, &conn->hcon->src);
4003 bacpy(&chan->dst, &conn->hcon->dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07004004 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
4005 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004006 chan->psm = psm;
4007 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07004008 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004009
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004010 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004011
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004012 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004013
Gustavo Padovan8d836d72013-10-15 19:24:47 -03004014 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004015
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03004016 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004017
Marcel Holtmann984947d2009-02-06 23:35:19 +01004018 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02004019 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07004020 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004021 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004022 result = L2CAP_CR_PEND;
4023 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08004024 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004025 } else {
Mat Martineau17009152012-10-23 15:24:07 -07004026 /* Force pending result for AMP controllers.
4027 * The connection will succeed after the
4028 * physical link is up.
4029 */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004030 if (amp_id == AMP_ID_BREDR) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004031 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau17009152012-10-23 15:24:07 -07004032 result = L2CAP_CR_SUCCESS;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004033 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004034 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004035 result = L2CAP_CR_PEND;
Mat Martineau17009152012-10-23 15:24:07 -07004036 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01004037 status = L2CAP_CS_NO_INFO;
4038 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004039 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004040 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004041 result = L2CAP_CR_PEND;
4042 status = L2CAP_CS_AUTHEN_PEND;
4043 }
4044 } else {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004045 l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004046 result = L2CAP_CR_PEND;
4047 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004048 }
4049
Linus Torvalds1da177e2005-04-16 15:20:36 -07004050response:
Gustavo Padovan8ffb9292013-10-21 14:21:41 -02004051 l2cap_chan_unlock(pchan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004052 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004053
4054sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07004055 rsp.scid = cpu_to_le16(scid);
4056 rsp.dcid = cpu_to_le16(dcid);
4057 rsp.result = cpu_to_le16(result);
4058 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03004059 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004060
4061 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
4062 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004063 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004064
4065 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
4066 conn->info_ident = l2cap_get_ident(conn);
4067
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004068 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004069
Gustavo Padovan2d792812012-10-06 10:07:01 +01004070 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
4071 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004072 }
4073
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004074 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01004075 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004076 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004077 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004078 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004079 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004080 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004081 }
Mat Martineau17009152012-10-23 15:24:07 -07004082
4083 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03004084}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004085
Mat Martineau4c89b6a2012-10-11 17:48:22 +03004086static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004087 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03004088{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05304089 struct hci_dev *hdev = conn->hcon->hdev;
4090 struct hci_conn *hcon = conn->hcon;
4091
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004092 if (cmd_len < sizeof(struct l2cap_conn_req))
4093 return -EPROTO;
4094
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05304095 hci_dev_lock(hdev);
4096 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
4097 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
4098 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
4099 hcon->dst_type, 0, NULL, 0,
4100 hcon->dev_class);
4101 hci_dev_unlock(hdev);
4102
Gustavo Padovan300229f2012-10-12 19:40:40 +08004103 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004104 return 0;
4105}
4106
Mat Martineau5909cf32012-10-23 15:24:08 -07004107static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004108 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4109 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004110{
4111 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
4112 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004113 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004114 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004115 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004116
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004117 if (cmd_len < sizeof(*rsp))
4118 return -EPROTO;
4119
Linus Torvalds1da177e2005-04-16 15:20:36 -07004120 scid = __le16_to_cpu(rsp->scid);
4121 dcid = __le16_to_cpu(rsp->dcid);
4122 result = __le16_to_cpu(rsp->result);
4123 status = __le16_to_cpu(rsp->status);
4124
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02004125 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 +01004126 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004127
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004128 mutex_lock(&conn->chan_lock);
4129
Linus Torvalds1da177e2005-04-16 15:20:36 -07004130 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004131 chan = __l2cap_get_chan_by_scid(conn, scid);
4132 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03004133 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004134 goto unlock;
4135 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004136 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004137 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
4138 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03004139 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004140 goto unlock;
4141 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004142 }
4143
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004144 err = 0;
4145
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004146 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004147
Linus Torvalds1da177e2005-04-16 15:20:36 -07004148 switch (result) {
4149 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03004150 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03004151 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004152 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004153 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01004154
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004155 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03004156 break;
4157
Linus Torvalds1da177e2005-04-16 15:20:36 -07004158 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004159 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004160 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004161 break;
4162
4163 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004164 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004165 break;
4166
4167 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004168 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004169 break;
4170 }
4171
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004172 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004173
4174unlock:
4175 mutex_unlock(&conn->chan_lock);
4176
4177 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004178}
4179
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004180static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07004181{
4182 /* FCS is enabled only in ERTM or streaming mode, if one or both
4183 * sides request it.
4184 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03004185 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004186 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02004187 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004188 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07004189}
4190
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004191static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
4192 u8 ident, u16 flags)
4193{
4194 struct l2cap_conn *conn = chan->conn;
4195
4196 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
4197 flags);
4198
4199 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
4200 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
4201
4202 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
4203 l2cap_build_conf_rsp(chan, data,
4204 L2CAP_CONF_SUCCESS, flags), data);
4205}
4206
Johan Hedberg662d6522013-10-16 11:20:47 +03004207static void cmd_reject_invalid_cid(struct l2cap_conn *conn, u8 ident,
4208 u16 scid, u16 dcid)
4209{
4210 struct l2cap_cmd_rej_cid rej;
4211
4212 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
4213 rej.scid = __cpu_to_le16(scid);
4214 rej.dcid = __cpu_to_le16(dcid);
4215
4216 l2cap_send_cmd(conn, ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
4217}
4218
Gustavo Padovan2d792812012-10-06 10:07:01 +01004219static inline int l2cap_config_req(struct l2cap_conn *conn,
4220 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4221 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004222{
4223 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
4224 u16 dcid, flags;
4225 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004226 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07004227 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004228
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004229 if (cmd_len < sizeof(*req))
4230 return -EPROTO;
4231
Linus Torvalds1da177e2005-04-16 15:20:36 -07004232 dcid = __le16_to_cpu(req->dcid);
4233 flags = __le16_to_cpu(req->flags);
4234
4235 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
4236
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004237 chan = l2cap_get_chan_by_scid(conn, dcid);
Johan Hedberg662d6522013-10-16 11:20:47 +03004238 if (!chan) {
4239 cmd_reject_invalid_cid(conn, cmd->ident, dcid, 0);
4240 return 0;
4241 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004242
David S. Miller033b1142011-07-21 13:38:42 -07004243 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Johan Hedberg662d6522013-10-16 11:20:47 +03004244 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4245 chan->dcid);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004246 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004247 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004248
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004249 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07004250 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004251 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004252 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004253 l2cap_build_conf_rsp(chan, rsp,
4254 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004255 goto unlock;
4256 }
4257
4258 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004259 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4260 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004261
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004262 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004263 /* Incomplete config. Send empty response. */
4264 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004265 l2cap_build_conf_rsp(chan, rsp,
4266 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004267 goto unlock;
4268 }
4269
4270 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004271 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004272 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004273 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004274 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004275 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004276
Mat Martineau1500109b2012-10-23 15:24:15 -07004277 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004278 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004279 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004280
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004281 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004282 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004283
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004284 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004285 goto unlock;
4286
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004287 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004288 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004289
Mat Martineau105bdf92012-04-27 16:50:48 -07004290 if (chan->mode == L2CAP_MODE_ERTM ||
4291 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004292 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004293
Mat Martineau3c588192012-04-11 10:48:42 -07004294 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004295 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004296 else
4297 l2cap_chan_ready(chan);
4298
Marcel Holtmann876d9482007-10-20 13:35:42 +02004299 goto unlock;
4300 }
4301
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004302 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004303 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004304 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004305 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004306 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004307 }
4308
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004309 /* Got Conf Rsp PENDING from remote side and asume we sent
4310 Conf Rsp PENDING in the code above */
4311 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004312 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004313
4314 /* check compatibility */
4315
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004316 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004317 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004318 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4319 else
4320 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004321 }
4322
Linus Torvalds1da177e2005-04-16 15:20:36 -07004323unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004324 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004325 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004326}
4327
Gustavo Padovan2d792812012-10-06 10:07:01 +01004328static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004329 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4330 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004331{
4332 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4333 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004334 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004335 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004336 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004337
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004338 if (cmd_len < sizeof(*rsp))
4339 return -EPROTO;
4340
Linus Torvalds1da177e2005-04-16 15:20:36 -07004341 scid = __le16_to_cpu(rsp->scid);
4342 flags = __le16_to_cpu(rsp->flags);
4343 result = __le16_to_cpu(rsp->result);
4344
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004345 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4346 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004347
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004348 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004349 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004350 return 0;
4351
4352 switch (result) {
4353 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004354 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004355 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004356 break;
4357
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004358 case L2CAP_CONF_PENDING:
4359 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4360
4361 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4362 char buf[64];
4363
4364 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004365 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004366 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004367 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004368 goto done;
4369 }
4370
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004371 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004372 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4373 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004374 } else {
4375 if (l2cap_check_efs(chan)) {
4376 amp_create_logical_link(chan);
4377 chan->ident = cmd->ident;
4378 }
4379 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004380 }
4381 goto done;
4382
Linus Torvalds1da177e2005-04-16 15:20:36 -07004383 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004384 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004385 char req[64];
4386
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004387 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004388 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004389 goto done;
4390 }
4391
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004392 /* throw out any old stored conf requests */
4393 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004394 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004395 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004396 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004397 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004398 goto done;
4399 }
4400
4401 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004402 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004403 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004404 if (result != L2CAP_CONF_SUCCESS)
4405 goto done;
4406 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004407 }
4408
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004409 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004410 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004411
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004412 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004413 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004414 goto done;
4415 }
4416
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004417 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004418 goto done;
4419
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004420 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004421
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004422 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004423 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004424
Mat Martineau105bdf92012-04-27 16:50:48 -07004425 if (chan->mode == L2CAP_MODE_ERTM ||
4426 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004427 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004428
Mat Martineau3c588192012-04-11 10:48:42 -07004429 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004430 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004431 else
4432 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004433 }
4434
4435done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004436 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004437 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004438}
4439
Gustavo Padovan2d792812012-10-06 10:07:01 +01004440static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004441 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4442 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004443{
4444 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4445 struct l2cap_disconn_rsp rsp;
4446 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004447 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004448
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004449 if (cmd_len != sizeof(*req))
4450 return -EPROTO;
4451
Linus Torvalds1da177e2005-04-16 15:20:36 -07004452 scid = __le16_to_cpu(req->scid);
4453 dcid = __le16_to_cpu(req->dcid);
4454
4455 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4456
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004457 mutex_lock(&conn->chan_lock);
4458
4459 chan = __l2cap_get_chan_by_scid(conn, dcid);
4460 if (!chan) {
4461 mutex_unlock(&conn->chan_lock);
Johan Hedberg662d6522013-10-16 11:20:47 +03004462 cmd_reject_invalid_cid(conn, cmd->ident, dcid, scid);
4463 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004464 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004465
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004466 l2cap_chan_lock(chan);
4467
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004468 rsp.dcid = cpu_to_le16(chan->scid);
4469 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004470 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4471
Gustavo Padovan5ec1bbe2013-10-15 19:24:48 -03004472 chan->ops->set_shutdown(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004473
Mat Martineau61d6ef32012-04-27 16:50:50 -07004474 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004475 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004476
4477 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004478
Gustavo Padovan80b98022012-05-27 22:27:51 -03004479 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004480 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004481
4482 mutex_unlock(&conn->chan_lock);
4483
Linus Torvalds1da177e2005-04-16 15:20:36 -07004484 return 0;
4485}
4486
Gustavo Padovan2d792812012-10-06 10:07:01 +01004487static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004488 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4489 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004490{
4491 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4492 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004493 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004494
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004495 if (cmd_len != sizeof(*rsp))
4496 return -EPROTO;
4497
Linus Torvalds1da177e2005-04-16 15:20:36 -07004498 scid = __le16_to_cpu(rsp->scid);
4499 dcid = __le16_to_cpu(rsp->dcid);
4500
4501 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4502
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004503 mutex_lock(&conn->chan_lock);
4504
4505 chan = __l2cap_get_chan_by_scid(conn, scid);
4506 if (!chan) {
4507 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004508 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004509 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004510
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004511 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004512
Mat Martineau61d6ef32012-04-27 16:50:50 -07004513 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004514 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004515
4516 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004517
Gustavo Padovan80b98022012-05-27 22:27:51 -03004518 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004519 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004520
4521 mutex_unlock(&conn->chan_lock);
4522
Linus Torvalds1da177e2005-04-16 15:20:36 -07004523 return 0;
4524}
4525
Gustavo Padovan2d792812012-10-06 10:07:01 +01004526static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004527 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4528 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004529{
4530 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004531 u16 type;
4532
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004533 if (cmd_len != sizeof(*req))
4534 return -EPROTO;
4535
Linus Torvalds1da177e2005-04-16 15:20:36 -07004536 type = __le16_to_cpu(req->type);
4537
4538 BT_DBG("type 0x%4.4x", type);
4539
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004540 if (type == L2CAP_IT_FEAT_MASK) {
4541 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004542 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004543 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004544 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4545 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004546 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004547 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004548 | L2CAP_FEAT_FCS;
Marcel Holtmann848566b2013-10-01 22:59:22 -07004549 if (conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004550 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004551 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004552
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004553 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004554 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4555 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004556 } else if (type == L2CAP_IT_FIXED_CHAN) {
4557 u8 buf[12];
4558 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004559
Marcel Holtmann848566b2013-10-01 22:59:22 -07004560 if (conn->hs_enabled)
Mat Martineau50a147c2011-11-02 16:18:34 -07004561 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4562 else
4563 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4564
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004565 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4566 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004567 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004568 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4569 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004570 } else {
4571 struct l2cap_info_rsp rsp;
4572 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004573 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004574 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4575 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004576 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004577
4578 return 0;
4579}
4580
Gustavo Padovan2d792812012-10-06 10:07:01 +01004581static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004582 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4583 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004584{
4585 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4586 u16 type, result;
4587
Jaganath Kanakkassery3f6fa3d2013-06-21 19:55:11 +05304588 if (cmd_len < sizeof(*rsp))
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004589 return -EPROTO;
4590
Linus Torvalds1da177e2005-04-16 15:20:36 -07004591 type = __le16_to_cpu(rsp->type);
4592 result = __le16_to_cpu(rsp->result);
4593
4594 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4595
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004596 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4597 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004598 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004599 return 0;
4600
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004601 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004602
Ville Tervoadb08ed2010-08-04 09:43:33 +03004603 if (result != L2CAP_IR_SUCCESS) {
4604 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4605 conn->info_ident = 0;
4606
4607 l2cap_conn_start(conn);
4608
4609 return 0;
4610 }
4611
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004612 switch (type) {
4613 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004614 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004615
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004616 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004617 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004618 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004619
4620 conn->info_ident = l2cap_get_ident(conn);
4621
4622 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004623 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004624 } else {
4625 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4626 conn->info_ident = 0;
4627
4628 l2cap_conn_start(conn);
4629 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004630 break;
4631
4632 case L2CAP_IT_FIXED_CHAN:
4633 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004634 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004635 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004636
4637 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004638 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004639 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004640
Linus Torvalds1da177e2005-04-16 15:20:36 -07004641 return 0;
4642}
4643
Mat Martineau17009152012-10-23 15:24:07 -07004644static int l2cap_create_channel_req(struct l2cap_conn *conn,
4645 struct l2cap_cmd_hdr *cmd,
4646 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004647{
4648 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004649 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004650 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004651 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004652 u16 psm, scid;
4653
4654 if (cmd_len != sizeof(*req))
4655 return -EPROTO;
4656
Marcel Holtmann848566b2013-10-01 22:59:22 -07004657 if (!conn->hs_enabled)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004658 return -EINVAL;
4659
4660 psm = le16_to_cpu(req->psm);
4661 scid = le16_to_cpu(req->scid);
4662
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004663 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 -07004664
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004665 /* For controller id 0 make BR/EDR connection */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004666 if (req->amp_id == AMP_ID_BREDR) {
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004667 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4668 req->amp_id);
4669 return 0;
4670 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004671
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004672 /* Validate AMP controller id */
4673 hdev = hci_dev_get(req->amp_id);
4674 if (!hdev)
4675 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004676
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004677 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004678 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004679 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004680 }
4681
4682 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4683 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004684 if (chan) {
4685 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4686 struct hci_conn *hs_hcon;
4687
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07004688 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
4689 &conn->hcon->dst);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004690 if (!hs_hcon) {
4691 hci_dev_put(hdev);
Johan Hedberg662d6522013-10-16 11:20:47 +03004692 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4693 chan->dcid);
4694 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004695 }
4696
4697 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4698
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004699 mgr->bredr_chan = chan;
4700 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004701 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004702 conn->mtu = hdev->block_mtu;
4703 }
4704
4705 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004706
4707 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004708
4709error:
4710 rsp.dcid = 0;
4711 rsp.scid = cpu_to_le16(scid);
4712 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4713 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4714
4715 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4716 sizeof(rsp), &rsp);
4717
Johan Hedbergdc280802013-09-16 13:05:13 +03004718 return 0;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004719}
4720
Mat Martineau8eb200b2012-10-23 15:24:17 -07004721static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4722{
4723 struct l2cap_move_chan_req req;
4724 u8 ident;
4725
4726 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4727
4728 ident = l2cap_get_ident(chan->conn);
4729 chan->ident = ident;
4730
4731 req.icid = cpu_to_le16(chan->scid);
4732 req.dest_amp_id = dest_amp_id;
4733
4734 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4735 &req);
4736
4737 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4738}
4739
Mat Martineau1500109b2012-10-23 15:24:15 -07004740static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004741{
4742 struct l2cap_move_chan_rsp rsp;
4743
Mat Martineau1500109b2012-10-23 15:24:15 -07004744 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004745
Mat Martineau1500109b2012-10-23 15:24:15 -07004746 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004747 rsp.result = cpu_to_le16(result);
4748
Mat Martineau1500109b2012-10-23 15:24:15 -07004749 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4750 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004751}
4752
Mat Martineau5b155ef2012-10-23 15:24:14 -07004753static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004754{
4755 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004756
Mat Martineau5b155ef2012-10-23 15:24:14 -07004757 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004758
Mat Martineau5b155ef2012-10-23 15:24:14 -07004759 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004760
Mat Martineau5b155ef2012-10-23 15:24:14 -07004761 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004762 cfm.result = cpu_to_le16(result);
4763
Mat Martineau5b155ef2012-10-23 15:24:14 -07004764 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4765 sizeof(cfm), &cfm);
4766
4767 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4768}
4769
4770static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4771{
4772 struct l2cap_move_chan_cfm cfm;
4773
4774 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4775
4776 cfm.icid = cpu_to_le16(icid);
4777 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4778
4779 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4780 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004781}
4782
4783static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004784 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004785{
4786 struct l2cap_move_chan_cfm_rsp rsp;
4787
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004788 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004789
4790 rsp.icid = cpu_to_le16(icid);
4791 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4792}
4793
Mat Martineau5f3847a2012-10-23 15:24:12 -07004794static void __release_logical_link(struct l2cap_chan *chan)
4795{
4796 chan->hs_hchan = NULL;
4797 chan->hs_hcon = NULL;
4798
4799 /* Placeholder - release the logical link */
4800}
4801
Mat Martineau1500109b2012-10-23 15:24:15 -07004802static void l2cap_logical_fail(struct l2cap_chan *chan)
4803{
4804 /* Logical link setup failed */
4805 if (chan->state != BT_CONNECTED) {
4806 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004807 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004808 return;
4809 }
4810
4811 switch (chan->move_role) {
4812 case L2CAP_MOVE_ROLE_RESPONDER:
4813 l2cap_move_done(chan);
4814 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4815 break;
4816 case L2CAP_MOVE_ROLE_INITIATOR:
4817 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4818 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4819 /* Remote has only sent pending or
4820 * success responses, clean up
4821 */
4822 l2cap_move_done(chan);
4823 }
4824
4825 /* Other amp move states imply that the move
4826 * has already aborted
4827 */
4828 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4829 break;
4830 }
4831}
4832
4833static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4834 struct hci_chan *hchan)
4835{
4836 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004837
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004838 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004839 chan->hs_hcon->l2cap_data = chan->conn;
4840
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004841 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004842
4843 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004844 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004845
4846 set_default_fcs(chan);
4847
4848 err = l2cap_ertm_init(chan);
4849 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004850 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004851 else
4852 l2cap_chan_ready(chan);
4853 }
4854}
4855
4856static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4857 struct hci_chan *hchan)
4858{
4859 chan->hs_hcon = hchan->conn;
4860 chan->hs_hcon->l2cap_data = chan->conn;
4861
4862 BT_DBG("move_state %d", chan->move_state);
4863
4864 switch (chan->move_state) {
4865 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4866 /* Move confirm will be sent after a success
4867 * response is received
4868 */
4869 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4870 break;
4871 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4872 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4873 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4874 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4875 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4876 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4877 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4878 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4879 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4880 }
4881 break;
4882 default:
4883 /* Move was not in expected state, free the channel */
4884 __release_logical_link(chan);
4885
4886 chan->move_state = L2CAP_MOVE_STABLE;
4887 }
4888}
4889
4890/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004891void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4892 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004893{
Mat Martineau1500109b2012-10-23 15:24:15 -07004894 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4895
4896 if (status) {
4897 l2cap_logical_fail(chan);
4898 __release_logical_link(chan);
4899 return;
4900 }
4901
4902 if (chan->state != BT_CONNECTED) {
4903 /* Ignore logical link if channel is on BR/EDR */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004904 if (chan->local_amp_id != AMP_ID_BREDR)
Mat Martineau1500109b2012-10-23 15:24:15 -07004905 l2cap_logical_finish_create(chan, hchan);
4906 } else {
4907 l2cap_logical_finish_move(chan, hchan);
4908 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004909}
4910
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004911void l2cap_move_start(struct l2cap_chan *chan)
4912{
4913 BT_DBG("chan %p", chan);
4914
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004915 if (chan->local_amp_id == AMP_ID_BREDR) {
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004916 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4917 return;
4918 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4919 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4920 /* Placeholder - start physical link setup */
4921 } else {
4922 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4923 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4924 chan->move_id = 0;
4925 l2cap_move_setup(chan);
4926 l2cap_send_move_chan_req(chan, 0);
4927 }
4928}
4929
Mat Martineau8eb200b2012-10-23 15:24:17 -07004930static void l2cap_do_create(struct l2cap_chan *chan, int result,
4931 u8 local_amp_id, u8 remote_amp_id)
4932{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004933 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4934 local_amp_id, remote_amp_id);
4935
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004936 chan->fcs = L2CAP_FCS_NONE;
4937
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004938 /* Outgoing channel on AMP */
4939 if (chan->state == BT_CONNECT) {
4940 if (result == L2CAP_CR_SUCCESS) {
4941 chan->local_amp_id = local_amp_id;
4942 l2cap_send_create_chan_req(chan, remote_amp_id);
4943 } else {
4944 /* Revert to BR/EDR connect */
4945 l2cap_send_conn_req(chan);
4946 }
4947
4948 return;
4949 }
4950
4951 /* Incoming channel on AMP */
4952 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004953 struct l2cap_conn_rsp rsp;
4954 char buf[128];
4955 rsp.scid = cpu_to_le16(chan->dcid);
4956 rsp.dcid = cpu_to_le16(chan->scid);
4957
Mat Martineau8eb200b2012-10-23 15:24:17 -07004958 if (result == L2CAP_CR_SUCCESS) {
4959 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004960 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4961 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004962 } else {
4963 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004964 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4965 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004966 }
4967
4968 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4969 sizeof(rsp), &rsp);
4970
4971 if (result == L2CAP_CR_SUCCESS) {
Gustavo Padovanf93fa272013-10-21 14:21:40 -02004972 l2cap_state_change(chan, BT_CONFIG);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004973 set_bit(CONF_REQ_SENT, &chan->conf_state);
4974 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4975 L2CAP_CONF_REQ,
4976 l2cap_build_conf_req(chan, buf), buf);
4977 chan->num_conf_req++;
4978 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004979 }
4980}
4981
4982static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4983 u8 remote_amp_id)
4984{
4985 l2cap_move_setup(chan);
4986 chan->move_id = local_amp_id;
4987 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4988
4989 l2cap_send_move_chan_req(chan, remote_amp_id);
4990}
4991
4992static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4993{
4994 struct hci_chan *hchan = NULL;
4995
4996 /* Placeholder - get hci_chan for logical link */
4997
4998 if (hchan) {
4999 if (hchan->state == BT_CONNECTED) {
5000 /* Logical link is ready to go */
5001 chan->hs_hcon = hchan->conn;
5002 chan->hs_hcon->l2cap_data = chan->conn;
5003 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
5004 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
5005
5006 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5007 } else {
5008 /* Wait for logical link to be ready */
5009 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5010 }
5011 } else {
5012 /* Logical link not available */
5013 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
5014 }
5015}
5016
5017static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
5018{
5019 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
5020 u8 rsp_result;
5021 if (result == -EINVAL)
5022 rsp_result = L2CAP_MR_BAD_ID;
5023 else
5024 rsp_result = L2CAP_MR_NOT_ALLOWED;
5025
5026 l2cap_send_move_chan_rsp(chan, rsp_result);
5027 }
5028
5029 chan->move_role = L2CAP_MOVE_ROLE_NONE;
5030 chan->move_state = L2CAP_MOVE_STABLE;
5031
5032 /* Restart data transmission */
5033 l2cap_ertm_send(chan);
5034}
5035
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02005036/* Invoke with locked chan */
5037void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07005038{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02005039 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02005040 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02005041
Mat Martineau8eb200b2012-10-23 15:24:17 -07005042 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
5043 chan, result, local_amp_id, remote_amp_id);
5044
Mat Martineau8eb200b2012-10-23 15:24:17 -07005045 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
5046 l2cap_chan_unlock(chan);
5047 return;
5048 }
5049
5050 if (chan->state != BT_CONNECTED) {
5051 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
5052 } else if (result != L2CAP_MR_SUCCESS) {
5053 l2cap_do_move_cancel(chan, result);
5054 } else {
5055 switch (chan->move_role) {
5056 case L2CAP_MOVE_ROLE_INITIATOR:
5057 l2cap_do_move_initiate(chan, local_amp_id,
5058 remote_amp_id);
5059 break;
5060 case L2CAP_MOVE_ROLE_RESPONDER:
5061 l2cap_do_move_respond(chan, result);
5062 break;
5063 default:
5064 l2cap_do_move_cancel(chan, result);
5065 break;
5066 }
5067 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07005068}
5069
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005070static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005071 struct l2cap_cmd_hdr *cmd,
5072 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005073{
5074 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07005075 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005076 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005077 u16 icid = 0;
5078 u16 result = L2CAP_MR_NOT_ALLOWED;
5079
5080 if (cmd_len != sizeof(*req))
5081 return -EPROTO;
5082
5083 icid = le16_to_cpu(req->icid);
5084
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005085 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005086
Marcel Holtmann848566b2013-10-01 22:59:22 -07005087 if (!conn->hs_enabled)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005088 return -EINVAL;
5089
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005090 chan = l2cap_get_chan_by_dcid(conn, icid);
5091 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07005092 rsp.icid = cpu_to_le16(icid);
5093 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
5094 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
5095 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005096 return 0;
5097 }
5098
Mat Martineau1500109b2012-10-23 15:24:15 -07005099 chan->ident = cmd->ident;
5100
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005101 if (chan->scid < L2CAP_CID_DYN_START ||
5102 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
5103 (chan->mode != L2CAP_MODE_ERTM &&
5104 chan->mode != L2CAP_MODE_STREAMING)) {
5105 result = L2CAP_MR_NOT_ALLOWED;
5106 goto send_move_response;
5107 }
5108
5109 if (chan->local_amp_id == req->dest_amp_id) {
5110 result = L2CAP_MR_SAME_ID;
5111 goto send_move_response;
5112 }
5113
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005114 if (req->dest_amp_id != AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005115 struct hci_dev *hdev;
5116 hdev = hci_dev_get(req->dest_amp_id);
5117 if (!hdev || hdev->dev_type != HCI_AMP ||
5118 !test_bit(HCI_UP, &hdev->flags)) {
5119 if (hdev)
5120 hci_dev_put(hdev);
5121
5122 result = L2CAP_MR_BAD_ID;
5123 goto send_move_response;
5124 }
5125 hci_dev_put(hdev);
5126 }
5127
5128 /* Detect a move collision. Only send a collision response
5129 * if this side has "lost", otherwise proceed with the move.
5130 * The winner has the larger bd_addr.
5131 */
5132 if ((__chan_is_moving(chan) ||
5133 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
Marcel Holtmann6f59b902013-10-13 05:24:01 -07005134 bacmp(&conn->hcon->src, &conn->hcon->dst) > 0) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005135 result = L2CAP_MR_COLLISION;
5136 goto send_move_response;
5137 }
5138
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005139 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5140 l2cap_move_setup(chan);
5141 chan->move_id = req->dest_amp_id;
5142 icid = chan->dcid;
5143
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005144 if (req->dest_amp_id == AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005145 /* Moving to BR/EDR */
5146 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5147 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
5148 result = L2CAP_MR_PEND;
5149 } else {
5150 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
5151 result = L2CAP_MR_SUCCESS;
5152 }
5153 } else {
5154 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
5155 /* Placeholder - uncomment when amp functions are available */
5156 /*amp_accept_physical(chan, req->dest_amp_id);*/
5157 result = L2CAP_MR_PEND;
5158 }
5159
5160send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07005161 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005162
Mat Martineau02b0fbb2012-10-23 15:24:10 -07005163 l2cap_chan_unlock(chan);
5164
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005165 return 0;
5166}
5167
Mat Martineau5b155ef2012-10-23 15:24:14 -07005168static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
5169{
5170 struct l2cap_chan *chan;
5171 struct hci_chan *hchan = NULL;
5172
5173 chan = l2cap_get_chan_by_scid(conn, icid);
5174 if (!chan) {
5175 l2cap_send_move_chan_cfm_icid(conn, icid);
5176 return;
5177 }
5178
5179 __clear_chan_timer(chan);
5180 if (result == L2CAP_MR_PEND)
5181 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
5182
5183 switch (chan->move_state) {
5184 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
5185 /* Move confirm will be sent when logical link
5186 * is complete.
5187 */
5188 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5189 break;
5190 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
5191 if (result == L2CAP_MR_PEND) {
5192 break;
5193 } else if (test_bit(CONN_LOCAL_BUSY,
5194 &chan->conn_state)) {
5195 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
5196 } else {
5197 /* Logical link is up or moving to BR/EDR,
5198 * proceed with move
5199 */
5200 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
5201 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5202 }
5203 break;
5204 case L2CAP_MOVE_WAIT_RSP:
5205 /* Moving to AMP */
5206 if (result == L2CAP_MR_SUCCESS) {
5207 /* Remote is ready, send confirm immediately
5208 * after logical link is ready
5209 */
5210 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
5211 } else {
5212 /* Both logical link and move success
5213 * are required to confirm
5214 */
5215 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
5216 }
5217
5218 /* Placeholder - get hci_chan for logical link */
5219 if (!hchan) {
5220 /* Logical link not available */
5221 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5222 break;
5223 }
5224
5225 /* If the logical link is not yet connected, do not
5226 * send confirmation.
5227 */
5228 if (hchan->state != BT_CONNECTED)
5229 break;
5230
5231 /* Logical link is already ready to go */
5232
5233 chan->hs_hcon = hchan->conn;
5234 chan->hs_hcon->l2cap_data = chan->conn;
5235
5236 if (result == L2CAP_MR_SUCCESS) {
5237 /* Can confirm now */
5238 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5239 } else {
5240 /* Now only need move success
5241 * to confirm
5242 */
5243 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
5244 }
5245
5246 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5247 break;
5248 default:
5249 /* Any other amp move state means the move failed. */
5250 chan->move_id = chan->local_amp_id;
5251 l2cap_move_done(chan);
5252 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5253 }
5254
5255 l2cap_chan_unlock(chan);
5256}
5257
5258static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5259 u16 result)
5260{
5261 struct l2cap_chan *chan;
5262
5263 chan = l2cap_get_chan_by_ident(conn, ident);
5264 if (!chan) {
5265 /* Could not locate channel, icid is best guess */
5266 l2cap_send_move_chan_cfm_icid(conn, icid);
5267 return;
5268 }
5269
5270 __clear_chan_timer(chan);
5271
5272 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5273 if (result == L2CAP_MR_COLLISION) {
5274 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5275 } else {
5276 /* Cleanup - cancel move */
5277 chan->move_id = chan->local_amp_id;
5278 l2cap_move_done(chan);
5279 }
5280 }
5281
5282 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5283
5284 l2cap_chan_unlock(chan);
5285}
5286
5287static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5288 struct l2cap_cmd_hdr *cmd,
5289 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005290{
5291 struct l2cap_move_chan_rsp *rsp = data;
5292 u16 icid, result;
5293
5294 if (cmd_len != sizeof(*rsp))
5295 return -EPROTO;
5296
5297 icid = le16_to_cpu(rsp->icid);
5298 result = le16_to_cpu(rsp->result);
5299
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005300 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005301
Mat Martineau5b155ef2012-10-23 15:24:14 -07005302 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5303 l2cap_move_continue(conn, icid, result);
5304 else
5305 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005306
5307 return 0;
5308}
5309
Mat Martineau5f3847a2012-10-23 15:24:12 -07005310static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5311 struct l2cap_cmd_hdr *cmd,
5312 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005313{
5314 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005315 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005316 u16 icid, result;
5317
5318 if (cmd_len != sizeof(*cfm))
5319 return -EPROTO;
5320
5321 icid = le16_to_cpu(cfm->icid);
5322 result = le16_to_cpu(cfm->result);
5323
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005324 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005325
Mat Martineau5f3847a2012-10-23 15:24:12 -07005326 chan = l2cap_get_chan_by_dcid(conn, icid);
5327 if (!chan) {
5328 /* Spec requires a response even if the icid was not found */
5329 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5330 return 0;
5331 }
5332
5333 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5334 if (result == L2CAP_MC_CONFIRMED) {
5335 chan->local_amp_id = chan->move_id;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005336 if (chan->local_amp_id == AMP_ID_BREDR)
Mat Martineau5f3847a2012-10-23 15:24:12 -07005337 __release_logical_link(chan);
5338 } else {
5339 chan->move_id = chan->local_amp_id;
5340 }
5341
5342 l2cap_move_done(chan);
5343 }
5344
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005345 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5346
Mat Martineau5f3847a2012-10-23 15:24:12 -07005347 l2cap_chan_unlock(chan);
5348
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005349 return 0;
5350}
5351
5352static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005353 struct l2cap_cmd_hdr *cmd,
5354 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005355{
5356 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005357 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005358 u16 icid;
5359
5360 if (cmd_len != sizeof(*rsp))
5361 return -EPROTO;
5362
5363 icid = le16_to_cpu(rsp->icid);
5364
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005365 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005366
Mat Martineau3fd71a02012-10-23 15:24:16 -07005367 chan = l2cap_get_chan_by_scid(conn, icid);
5368 if (!chan)
5369 return 0;
5370
5371 __clear_chan_timer(chan);
5372
5373 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5374 chan->local_amp_id = chan->move_id;
5375
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005376 if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan)
Mat Martineau3fd71a02012-10-23 15:24:16 -07005377 __release_logical_link(chan);
5378
5379 l2cap_move_done(chan);
5380 }
5381
5382 l2cap_chan_unlock(chan);
5383
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005384 return 0;
5385}
5386
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005387static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005388 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005389{
5390 u16 max_latency;
5391
5392 if (min > max || min < 6 || max > 3200)
5393 return -EINVAL;
5394
5395 if (to_multiplier < 10 || to_multiplier > 3200)
5396 return -EINVAL;
5397
5398 if (max >= to_multiplier * 8)
5399 return -EINVAL;
5400
5401 max_latency = (to_multiplier * 8 / max) - 1;
5402 if (latency > 499 || latency > max_latency)
5403 return -EINVAL;
5404
5405 return 0;
5406}
5407
5408static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005409 struct l2cap_cmd_hdr *cmd,
Johan Hedberg203e6392013-05-15 10:07:15 +03005410 u16 cmd_len, u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005411{
5412 struct hci_conn *hcon = conn->hcon;
5413 struct l2cap_conn_param_update_req *req;
5414 struct l2cap_conn_param_update_rsp rsp;
Johan Hedberg203e6392013-05-15 10:07:15 +03005415 u16 min, max, latency, to_multiplier;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005416 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005417
5418 if (!(hcon->link_mode & HCI_LM_MASTER))
5419 return -EINVAL;
5420
Claudio Takahaside731152011-02-11 19:28:55 -02005421 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5422 return -EPROTO;
5423
5424 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005425 min = __le16_to_cpu(req->min);
5426 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005427 latency = __le16_to_cpu(req->latency);
5428 to_multiplier = __le16_to_cpu(req->to_multiplier);
5429
5430 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 +01005431 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005432
5433 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005434
5435 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5436 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005437 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005438 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005439 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005440
5441 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005442 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005443
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005444 if (!err)
5445 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5446
Claudio Takahaside731152011-02-11 19:28:55 -02005447 return 0;
5448}
5449
Johan Hedbergf1496de2013-05-13 14:15:56 +03005450static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
5451 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5452 u8 *data)
5453{
5454 struct l2cap_le_conn_rsp *rsp = (struct l2cap_le_conn_rsp *) data;
5455 u16 dcid, mtu, mps, credits, result;
5456 struct l2cap_chan *chan;
5457 int err;
5458
5459 if (cmd_len < sizeof(*rsp))
5460 return -EPROTO;
5461
5462 dcid = __le16_to_cpu(rsp->dcid);
5463 mtu = __le16_to_cpu(rsp->mtu);
5464 mps = __le16_to_cpu(rsp->mps);
5465 credits = __le16_to_cpu(rsp->credits);
5466 result = __le16_to_cpu(rsp->result);
5467
5468 if (result == L2CAP_CR_SUCCESS && (mtu < 23 || mps < 23))
5469 return -EPROTO;
5470
5471 BT_DBG("dcid 0x%4.4x mtu %u mps %u credits %u result 0x%2.2x",
5472 dcid, mtu, mps, credits, result);
5473
5474 mutex_lock(&conn->chan_lock);
5475
5476 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
5477 if (!chan) {
5478 err = -EBADSLT;
5479 goto unlock;
5480 }
5481
5482 err = 0;
5483
5484 l2cap_chan_lock(chan);
5485
5486 switch (result) {
5487 case L2CAP_CR_SUCCESS:
5488 chan->ident = 0;
5489 chan->dcid = dcid;
5490 chan->omtu = mtu;
5491 chan->remote_mps = mps;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005492 chan->tx_credits = credits;
Johan Hedbergf1496de2013-05-13 14:15:56 +03005493 l2cap_chan_ready(chan);
5494 break;
5495
5496 default:
5497 l2cap_chan_del(chan, ECONNREFUSED);
5498 break;
5499 }
5500
5501 l2cap_chan_unlock(chan);
5502
5503unlock:
5504 mutex_unlock(&conn->chan_lock);
5505
5506 return err;
5507}
5508
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005509static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005510 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5511 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005512{
5513 int err = 0;
5514
5515 switch (cmd->code) {
5516 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005517 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005518 break;
5519
5520 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005521 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005522 break;
5523
5524 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005525 case L2CAP_CREATE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005526 l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005527 break;
5528
5529 case L2CAP_CONF_REQ:
5530 err = l2cap_config_req(conn, cmd, cmd_len, data);
5531 break;
5532
5533 case L2CAP_CONF_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005534 l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005535 break;
5536
5537 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005538 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005539 break;
5540
5541 case L2CAP_DISCONN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005542 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005543 break;
5544
5545 case L2CAP_ECHO_REQ:
5546 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5547 break;
5548
5549 case L2CAP_ECHO_RSP:
5550 break;
5551
5552 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005553 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005554 break;
5555
5556 case L2CAP_INFO_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005557 l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005558 break;
5559
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005560 case L2CAP_CREATE_CHAN_REQ:
5561 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5562 break;
5563
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005564 case L2CAP_MOVE_CHAN_REQ:
5565 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5566 break;
5567
5568 case L2CAP_MOVE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005569 l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005570 break;
5571
5572 case L2CAP_MOVE_CHAN_CFM:
5573 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5574 break;
5575
5576 case L2CAP_MOVE_CHAN_CFM_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005577 l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005578 break;
5579
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005580 default:
5581 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5582 err = -EINVAL;
5583 break;
5584 }
5585
5586 return err;
5587}
5588
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005589static int l2cap_le_connect_req(struct l2cap_conn *conn,
5590 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5591 u8 *data)
5592{
5593 struct l2cap_le_conn_req *req = (struct l2cap_le_conn_req *) data;
5594 struct l2cap_le_conn_rsp rsp;
5595 struct l2cap_chan *chan, *pchan;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005596 u16 dcid, scid, credits, mtu, mps;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005597 __le16 psm;
5598 u8 result;
5599
5600 if (cmd_len != sizeof(*req))
5601 return -EPROTO;
5602
5603 scid = __le16_to_cpu(req->scid);
5604 mtu = __le16_to_cpu(req->mtu);
5605 mps = __le16_to_cpu(req->mps);
5606 psm = req->psm;
5607 dcid = 0;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005608 credits = 0;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005609
5610 if (mtu < 23 || mps < 23)
5611 return -EPROTO;
5612
5613 BT_DBG("psm 0x%2.2x scid 0x%4.4x mtu %u mps %u", __le16_to_cpu(psm),
5614 scid, mtu, mps);
5615
5616 /* Check if we have socket listening on psm */
5617 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
5618 &conn->hcon->dst, LE_LINK);
5619 if (!pchan) {
5620 result = L2CAP_CR_BAD_PSM;
5621 chan = NULL;
5622 goto response;
5623 }
5624
5625 mutex_lock(&conn->chan_lock);
5626 l2cap_chan_lock(pchan);
5627
5628 if (!smp_sufficient_security(conn->hcon, pchan->sec_level)) {
5629 result = L2CAP_CR_AUTHENTICATION;
5630 chan = NULL;
5631 goto response_unlock;
5632 }
5633
5634 /* Check if we already have channel with that dcid */
5635 if (__l2cap_get_chan_by_dcid(conn, scid)) {
5636 result = L2CAP_CR_NO_MEM;
5637 chan = NULL;
5638 goto response_unlock;
5639 }
5640
5641 chan = pchan->ops->new_connection(pchan);
5642 if (!chan) {
5643 result = L2CAP_CR_NO_MEM;
5644 goto response_unlock;
5645 }
5646
5647 bacpy(&chan->src, &conn->hcon->src);
5648 bacpy(&chan->dst, &conn->hcon->dst);
5649 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
5650 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
5651 chan->psm = psm;
5652 chan->dcid = scid;
5653 chan->omtu = mtu;
5654 chan->remote_mps = mps;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005655 chan->tx_credits = __le16_to_cpu(req->credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005656
5657 __l2cap_chan_add(conn, chan);
5658 dcid = chan->scid;
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005659 credits = chan->rx_credits;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005660
5661 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
5662
5663 chan->ident = cmd->ident;
5664
5665 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
5666 l2cap_state_change(chan, BT_CONNECT2);
5667 result = L2CAP_CR_PEND;
5668 chan->ops->defer(chan);
5669 } else {
5670 l2cap_chan_ready(chan);
5671 result = L2CAP_CR_SUCCESS;
5672 }
5673
5674response_unlock:
5675 l2cap_chan_unlock(pchan);
5676 mutex_unlock(&conn->chan_lock);
5677
5678 if (result == L2CAP_CR_PEND)
5679 return 0;
5680
5681response:
5682 if (chan) {
5683 rsp.mtu = cpu_to_le16(chan->imtu);
Johan Hedberg3916aed2013-10-07 15:35:26 +02005684 rsp.mps = cpu_to_le16(chan->mps);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005685 } else {
5686 rsp.mtu = 0;
5687 rsp.mps = 0;
5688 }
5689
5690 rsp.dcid = cpu_to_le16(dcid);
Johan Hedberg0cd75f72013-05-17 13:09:05 +03005691 rsp.credits = cpu_to_le16(credits);
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005692 rsp.result = cpu_to_le16(result);
5693
5694 l2cap_send_cmd(conn, cmd->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), &rsp);
5695
5696 return 0;
5697}
5698
Johan Hedbergfad5fc892013-12-05 09:45:01 +02005699static inline int l2cap_le_credits(struct l2cap_conn *conn,
5700 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5701 u8 *data)
5702{
5703 struct l2cap_le_credits *pkt;
5704 struct l2cap_chan *chan;
5705 u16 cid, credits;
5706
5707 if (cmd_len != sizeof(*pkt))
5708 return -EPROTO;
5709
5710 pkt = (struct l2cap_le_credits *) data;
5711 cid = __le16_to_cpu(pkt->cid);
5712 credits = __le16_to_cpu(pkt->credits);
5713
5714 BT_DBG("cid 0x%4.4x credits 0x%4.4x", cid, credits);
5715
5716 chan = l2cap_get_chan_by_dcid(conn, cid);
5717 if (!chan)
5718 return -EBADSLT;
5719
5720 chan->tx_credits += credits;
5721
5722 while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
5723 l2cap_do_send(chan, skb_dequeue(&chan->tx_q));
5724 chan->tx_credits--;
5725 }
5726
5727 if (chan->tx_credits)
5728 chan->ops->resume(chan);
5729
5730 l2cap_chan_unlock(chan);
5731
5732 return 0;
5733}
5734
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005735static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Johan Hedberg203e6392013-05-15 10:07:15 +03005736 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5737 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005738{
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005739 int err = 0;
5740
Johan Hedberg3af8ace2013-12-03 09:51:51 +02005741 if (!enable_lecoc) {
5742 switch (cmd->code) {
5743 case L2CAP_LE_CONN_REQ:
5744 case L2CAP_LE_CONN_RSP:
5745 case L2CAP_LE_CREDITS:
5746 case L2CAP_DISCONN_REQ:
5747 case L2CAP_DISCONN_RSP:
5748 return -EINVAL;
5749 }
5750 }
5751
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005752 switch (cmd->code) {
5753 case L2CAP_COMMAND_REJ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005754 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005755
5756 case L2CAP_CONN_PARAM_UPDATE_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005757 err = l2cap_conn_param_update_req(conn, cmd, cmd_len, data);
5758 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005759
5760 case L2CAP_CONN_PARAM_UPDATE_RSP:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005761 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005762
Johan Hedbergf1496de2013-05-13 14:15:56 +03005763 case L2CAP_LE_CONN_RSP:
5764 l2cap_le_connect_rsp(conn, cmd, cmd_len, data);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005765 break;
Johan Hedbergf1496de2013-05-13 14:15:56 +03005766
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005767 case L2CAP_LE_CONN_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005768 err = l2cap_le_connect_req(conn, cmd, cmd_len, data);
5769 break;
Johan Hedberg27e2d4c2013-05-14 13:27:21 +03005770
Johan Hedbergfad5fc892013-12-05 09:45:01 +02005771 case L2CAP_LE_CREDITS:
5772 err = l2cap_le_credits(conn, cmd, cmd_len, data);
5773 break;
5774
Johan Hedberg3defe012013-05-15 10:16:06 +03005775 case L2CAP_DISCONN_REQ:
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005776 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
5777 break;
Johan Hedberg3defe012013-05-15 10:16:06 +03005778
5779 case L2CAP_DISCONN_RSP:
5780 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005781 break;
Johan Hedberg3defe012013-05-15 10:16:06 +03005782
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005783 default:
5784 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005785 err = -EINVAL;
5786 break;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005787 }
Johan Hedbergb5ecba62013-12-02 12:21:29 +02005788
5789 return err;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005790}
5791
Johan Hedbergc5623552013-04-29 19:35:33 +03005792static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5793 struct sk_buff *skb)
5794{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005795 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005796 struct l2cap_cmd_hdr *cmd;
5797 u16 len;
Johan Hedbergc5623552013-04-29 19:35:33 +03005798 int err;
5799
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005800 if (hcon->type != LE_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005801 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005802
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005803 if (skb->len < L2CAP_CMD_HDR_SIZE)
5804 goto drop;
Johan Hedbergc5623552013-04-29 19:35:33 +03005805
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005806 cmd = (void *) skb->data;
5807 skb_pull(skb, L2CAP_CMD_HDR_SIZE);
Johan Hedbergc5623552013-04-29 19:35:33 +03005808
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005809 len = le16_to_cpu(cmd->len);
Johan Hedbergc5623552013-04-29 19:35:33 +03005810
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005811 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, cmd->ident);
Johan Hedbergc5623552013-04-29 19:35:33 +03005812
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005813 if (len != skb->len || !cmd->ident) {
5814 BT_DBG("corrupted command");
5815 goto drop;
5816 }
Johan Hedbergc5623552013-04-29 19:35:33 +03005817
Johan Hedberg203e6392013-05-15 10:07:15 +03005818 err = l2cap_le_sig_cmd(conn, cmd, len, skb->data);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005819 if (err) {
5820 struct l2cap_cmd_rej_unk rej;
Johan Hedbergc5623552013-04-29 19:35:33 +03005821
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005822 BT_ERR("Wrong link type (%d)", err);
Johan Hedbergc5623552013-04-29 19:35:33 +03005823
Johan Hedberga5211492013-10-16 11:20:49 +03005824 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005825 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
5826 sizeof(rej), &rej);
Johan Hedbergc5623552013-04-29 19:35:33 +03005827 }
5828
Marcel Holtmann3b166292013-10-02 08:28:21 -07005829drop:
Johan Hedbergc5623552013-04-29 19:35:33 +03005830 kfree_skb(skb);
5831}
5832
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005833static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005834 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005835{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005836 struct hci_conn *hcon = conn->hcon;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005837 u8 *data = skb->data;
5838 int len = skb->len;
5839 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005840 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005841
5842 l2cap_raw_recv(conn, skb);
5843
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005844 if (hcon->type != ACL_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005845 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005846
Linus Torvalds1da177e2005-04-16 15:20:36 -07005847 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005848 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005849 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5850 data += L2CAP_CMD_HDR_SIZE;
5851 len -= L2CAP_CMD_HDR_SIZE;
5852
Al Viro88219a02007-07-29 00:17:25 -07005853 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005854
Gustavo Padovan2d792812012-10-06 10:07:01 +01005855 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5856 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005857
Al Viro88219a02007-07-29 00:17:25 -07005858 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005859 BT_DBG("corrupted command");
5860 break;
5861 }
5862
Johan Hedbergc5623552013-04-29 19:35:33 +03005863 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005864 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005865 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005866
5867 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005868
Johan Hedberga5211492013-10-16 11:20:49 +03005869 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005870 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5871 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005872 }
5873
Al Viro88219a02007-07-29 00:17:25 -07005874 data += cmd_len;
5875 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005876 }
5877
Marcel Holtmann3b166292013-10-02 08:28:21 -07005878drop:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005879 kfree_skb(skb);
5880}
5881
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005882static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005883{
5884 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005885 int hdr_size;
5886
5887 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5888 hdr_size = L2CAP_EXT_HDR_SIZE;
5889 else
5890 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005891
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005892 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005893 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005894 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5895 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5896
5897 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005898 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005899 }
5900 return 0;
5901}
5902
Mat Martineau6ea00482012-05-17 20:53:52 -07005903static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005904{
Mat Martineaue31f7632012-05-17 20:53:41 -07005905 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005906
Mat Martineaue31f7632012-05-17 20:53:41 -07005907 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005908
Mat Martineaue31f7632012-05-17 20:53:41 -07005909 memset(&control, 0, sizeof(control));
5910 control.sframe = 1;
5911 control.final = 1;
5912 control.reqseq = chan->buffer_seq;
5913 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005914
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005915 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005916 control.super = L2CAP_SUPER_RNR;
5917 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005918 }
5919
Mat Martineaue31f7632012-05-17 20:53:41 -07005920 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5921 chan->unacked_frames > 0)
5922 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005923
Mat Martineaue31f7632012-05-17 20:53:41 -07005924 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005925 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005926
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005927 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005928 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5929 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5930 * send it now.
5931 */
5932 control.super = L2CAP_SUPER_RR;
5933 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005934 }
5935}
5936
Gustavo Padovan2d792812012-10-06 10:07:01 +01005937static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5938 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005939{
Mat Martineau84084a32011-07-22 14:54:00 -07005940 /* skb->len reflects data in skb as well as all fragments
5941 * skb->data_len reflects only data in fragments
5942 */
5943 if (!skb_has_frag_list(skb))
5944 skb_shinfo(skb)->frag_list = new_frag;
5945
5946 new_frag->next = NULL;
5947
5948 (*last_frag)->next = new_frag;
5949 *last_frag = new_frag;
5950
5951 skb->len += new_frag->len;
5952 skb->data_len += new_frag->len;
5953 skb->truesize += new_frag->truesize;
5954}
5955
Mat Martineau4b51dae92012-05-17 20:53:37 -07005956static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5957 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005958{
5959 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005960
Mat Martineau4b51dae92012-05-17 20:53:37 -07005961 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005962 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005963 if (chan->sdu)
5964 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005965
Gustavo Padovan80b98022012-05-27 22:27:51 -03005966 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005967 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005968
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005969 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005970 if (chan->sdu)
5971 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005972
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005973 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005974 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005975
Mat Martineau84084a32011-07-22 14:54:00 -07005976 if (chan->sdu_len > chan->imtu) {
5977 err = -EMSGSIZE;
5978 break;
5979 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005980
Mat Martineau84084a32011-07-22 14:54:00 -07005981 if (skb->len >= chan->sdu_len)
5982 break;
5983
5984 chan->sdu = skb;
5985 chan->sdu_last_frag = skb;
5986
5987 skb = NULL;
5988 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005989 break;
5990
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005991 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005992 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005993 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005994
Mat Martineau84084a32011-07-22 14:54:00 -07005995 append_skb_frag(chan->sdu, skb,
5996 &chan->sdu_last_frag);
5997 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005998
Mat Martineau84084a32011-07-22 14:54:00 -07005999 if (chan->sdu->len >= chan->sdu_len)
6000 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03006001
Mat Martineau84084a32011-07-22 14:54:00 -07006002 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006003 break;
6004
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03006005 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03006006 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07006007 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006008
Mat Martineau84084a32011-07-22 14:54:00 -07006009 append_skb_frag(chan->sdu, skb,
6010 &chan->sdu_last_frag);
6011 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006012
Mat Martineau84084a32011-07-22 14:54:00 -07006013 if (chan->sdu->len != chan->sdu_len)
6014 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006015
Gustavo Padovan80b98022012-05-27 22:27:51 -03006016 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03006017
Mat Martineau84084a32011-07-22 14:54:00 -07006018 if (!err) {
6019 /* Reassembly complete */
6020 chan->sdu = NULL;
6021 chan->sdu_last_frag = NULL;
6022 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03006023 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006024 break;
6025 }
6026
Mat Martineau84084a32011-07-22 14:54:00 -07006027 if (err) {
6028 kfree_skb(skb);
6029 kfree_skb(chan->sdu);
6030 chan->sdu = NULL;
6031 chan->sdu_last_frag = NULL;
6032 chan->sdu_len = 0;
6033 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006034
Mat Martineau84084a32011-07-22 14:54:00 -07006035 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03006036}
6037
Mat Martineau32b32732012-10-23 15:24:11 -07006038static int l2cap_resegment(struct l2cap_chan *chan)
6039{
6040 /* Placeholder */
6041 return 0;
6042}
6043
Mat Martineaue3281402011-07-07 09:39:02 -07006044void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03006045{
Mat Martineau61aa4f52012-05-17 20:53:40 -07006046 u8 event;
6047
6048 if (chan->mode != L2CAP_MODE_ERTM)
6049 return;
6050
6051 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03006052 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03006053}
6054
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006055static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
6056{
Mat Martineau63838722012-05-17 20:53:45 -07006057 int err = 0;
6058 /* Pass sequential frames to l2cap_reassemble_sdu()
6059 * until a gap is encountered.
6060 */
6061
6062 BT_DBG("chan %p", chan);
6063
6064 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6065 struct sk_buff *skb;
6066 BT_DBG("Searching for skb with txseq %d (queue len %d)",
6067 chan->buffer_seq, skb_queue_len(&chan->srej_q));
6068
6069 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
6070
6071 if (!skb)
6072 break;
6073
6074 skb_unlink(skb, &chan->srej_q);
6075 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6076 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
6077 if (err)
6078 break;
6079 }
6080
6081 if (skb_queue_empty(&chan->srej_q)) {
6082 chan->rx_state = L2CAP_RX_STATE_RECV;
6083 l2cap_send_ack(chan);
6084 }
6085
6086 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006087}
6088
6089static void l2cap_handle_srej(struct l2cap_chan *chan,
6090 struct l2cap_ctrl *control)
6091{
Mat Martineauf80842a2012-05-17 20:53:46 -07006092 struct sk_buff *skb;
6093
6094 BT_DBG("chan %p, control %p", chan, control);
6095
6096 if (control->reqseq == chan->next_tx_seq) {
6097 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006098 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07006099 return;
6100 }
6101
6102 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
6103
6104 if (skb == NULL) {
6105 BT_DBG("Seq %d not available for retransmission",
6106 control->reqseq);
6107 return;
6108 }
6109
6110 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
6111 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006112 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07006113 return;
6114 }
6115
6116 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6117
6118 if (control->poll) {
6119 l2cap_pass_to_tx(chan, control);
6120
6121 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6122 l2cap_retransmit(chan, control);
6123 l2cap_ertm_send(chan);
6124
6125 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
6126 set_bit(CONN_SREJ_ACT, &chan->conn_state);
6127 chan->srej_save_reqseq = control->reqseq;
6128 }
6129 } else {
6130 l2cap_pass_to_tx_fbit(chan, control);
6131
6132 if (control->final) {
6133 if (chan->srej_save_reqseq != control->reqseq ||
6134 !test_and_clear_bit(CONN_SREJ_ACT,
6135 &chan->conn_state))
6136 l2cap_retransmit(chan, control);
6137 } else {
6138 l2cap_retransmit(chan, control);
6139 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
6140 set_bit(CONN_SREJ_ACT, &chan->conn_state);
6141 chan->srej_save_reqseq = control->reqseq;
6142 }
6143 }
6144 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006145}
6146
6147static void l2cap_handle_rej(struct l2cap_chan *chan,
6148 struct l2cap_ctrl *control)
6149{
Mat Martineaufcd289d2012-05-17 20:53:47 -07006150 struct sk_buff *skb;
6151
6152 BT_DBG("chan %p, control %p", chan, control);
6153
6154 if (control->reqseq == chan->next_tx_seq) {
6155 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006156 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07006157 return;
6158 }
6159
6160 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
6161
6162 if (chan->max_tx && skb &&
6163 bt_cb(skb)->control.retries >= chan->max_tx) {
6164 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006165 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07006166 return;
6167 }
6168
6169 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6170
6171 l2cap_pass_to_tx(chan, control);
6172
6173 if (control->final) {
6174 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
6175 l2cap_retransmit_all(chan, control);
6176 } else {
6177 l2cap_retransmit_all(chan, control);
6178 l2cap_ertm_send(chan);
6179 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
6180 set_bit(CONN_REJ_ACT, &chan->conn_state);
6181 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006182}
6183
Mat Martineau4b51dae92012-05-17 20:53:37 -07006184static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
6185{
6186 BT_DBG("chan %p, txseq %d", chan, txseq);
6187
6188 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
6189 chan->expected_tx_seq);
6190
6191 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
6192 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01006193 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07006194 /* See notes below regarding "double poll" and
6195 * invalid packets.
6196 */
6197 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
6198 BT_DBG("Invalid/Ignore - after SREJ");
6199 return L2CAP_TXSEQ_INVALID_IGNORE;
6200 } else {
6201 BT_DBG("Invalid - in window after SREJ sent");
6202 return L2CAP_TXSEQ_INVALID;
6203 }
6204 }
6205
6206 if (chan->srej_list.head == txseq) {
6207 BT_DBG("Expected SREJ");
6208 return L2CAP_TXSEQ_EXPECTED_SREJ;
6209 }
6210
6211 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
6212 BT_DBG("Duplicate SREJ - txseq already stored");
6213 return L2CAP_TXSEQ_DUPLICATE_SREJ;
6214 }
6215
6216 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
6217 BT_DBG("Unexpected SREJ - not requested");
6218 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
6219 }
6220 }
6221
6222 if (chan->expected_tx_seq == txseq) {
6223 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
6224 chan->tx_win) {
6225 BT_DBG("Invalid - txseq outside tx window");
6226 return L2CAP_TXSEQ_INVALID;
6227 } else {
6228 BT_DBG("Expected");
6229 return L2CAP_TXSEQ_EXPECTED;
6230 }
6231 }
6232
6233 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01006234 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07006235 BT_DBG("Duplicate - expected_tx_seq later than txseq");
6236 return L2CAP_TXSEQ_DUPLICATE;
6237 }
6238
6239 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
6240 /* A source of invalid packets is a "double poll" condition,
6241 * where delays cause us to send multiple poll packets. If
6242 * the remote stack receives and processes both polls,
6243 * sequence numbers can wrap around in such a way that a
6244 * resent frame has a sequence number that looks like new data
6245 * with a sequence gap. This would trigger an erroneous SREJ
6246 * request.
6247 *
6248 * Fortunately, this is impossible with a tx window that's
6249 * less than half of the maximum sequence number, which allows
6250 * invalid frames to be safely ignored.
6251 *
6252 * With tx window sizes greater than half of the tx window
6253 * maximum, the frame is invalid and cannot be ignored. This
6254 * causes a disconnect.
6255 */
6256
6257 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
6258 BT_DBG("Invalid/Ignore - txseq outside tx window");
6259 return L2CAP_TXSEQ_INVALID_IGNORE;
6260 } else {
6261 BT_DBG("Invalid - txseq outside tx window");
6262 return L2CAP_TXSEQ_INVALID;
6263 }
6264 } else {
6265 BT_DBG("Unexpected - txseq indicates missing frames");
6266 return L2CAP_TXSEQ_UNEXPECTED;
6267 }
6268}
6269
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006270static int l2cap_rx_state_recv(struct l2cap_chan *chan,
6271 struct l2cap_ctrl *control,
6272 struct sk_buff *skb, u8 event)
6273{
6274 int err = 0;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006275 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006276
6277 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6278 event);
6279
6280 switch (event) {
6281 case L2CAP_EV_RECV_IFRAME:
6282 switch (l2cap_classify_txseq(chan, control->txseq)) {
6283 case L2CAP_TXSEQ_EXPECTED:
6284 l2cap_pass_to_tx(chan, control);
6285
6286 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6287 BT_DBG("Busy, discarding expected seq %d",
6288 control->txseq);
6289 break;
6290 }
6291
6292 chan->expected_tx_seq = __next_seq(chan,
6293 control->txseq);
6294
6295 chan->buffer_seq = chan->expected_tx_seq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006296 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006297
6298 err = l2cap_reassemble_sdu(chan, skb, control);
6299 if (err)
6300 break;
6301
6302 if (control->final) {
6303 if (!test_and_clear_bit(CONN_REJ_ACT,
6304 &chan->conn_state)) {
6305 control->final = 0;
6306 l2cap_retransmit_all(chan, control);
6307 l2cap_ertm_send(chan);
6308 }
6309 }
6310
6311 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
6312 l2cap_send_ack(chan);
6313 break;
6314 case L2CAP_TXSEQ_UNEXPECTED:
6315 l2cap_pass_to_tx(chan, control);
6316
6317 /* Can't issue SREJ frames in the local busy state.
6318 * Drop this frame, it will be seen as missing
6319 * when local busy is exited.
6320 */
6321 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
6322 BT_DBG("Busy, discarding unexpected seq %d",
6323 control->txseq);
6324 break;
6325 }
6326
6327 /* There was a gap in the sequence, so an SREJ
6328 * must be sent for each missing frame. The
6329 * current frame is stored for later use.
6330 */
6331 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006332 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006333 BT_DBG("Queued %p (queue len %d)", skb,
6334 skb_queue_len(&chan->srej_q));
6335
6336 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
6337 l2cap_seq_list_clear(&chan->srej_list);
6338 l2cap_send_srej(chan, control->txseq);
6339
6340 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
6341 break;
6342 case L2CAP_TXSEQ_DUPLICATE:
6343 l2cap_pass_to_tx(chan, control);
6344 break;
6345 case L2CAP_TXSEQ_INVALID_IGNORE:
6346 break;
6347 case L2CAP_TXSEQ_INVALID:
6348 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006349 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006350 break;
6351 }
6352 break;
6353 case L2CAP_EV_RECV_RR:
6354 l2cap_pass_to_tx(chan, control);
6355 if (control->final) {
6356 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6357
Mat Martineaue6a3ee62012-10-23 15:24:22 -07006358 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
6359 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006360 control->final = 0;
6361 l2cap_retransmit_all(chan, control);
6362 }
6363
6364 l2cap_ertm_send(chan);
6365 } else if (control->poll) {
6366 l2cap_send_i_or_rr_or_rnr(chan);
6367 } else {
6368 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6369 &chan->conn_state) &&
6370 chan->unacked_frames)
6371 __set_retrans_timer(chan);
6372
6373 l2cap_ertm_send(chan);
6374 }
6375 break;
6376 case L2CAP_EV_RECV_RNR:
6377 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6378 l2cap_pass_to_tx(chan, control);
6379 if (control && control->poll) {
6380 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6381 l2cap_send_rr_or_rnr(chan, 0);
6382 }
6383 __clear_retrans_timer(chan);
6384 l2cap_seq_list_clear(&chan->retrans_list);
6385 break;
6386 case L2CAP_EV_RECV_REJ:
6387 l2cap_handle_rej(chan, control);
6388 break;
6389 case L2CAP_EV_RECV_SREJ:
6390 l2cap_handle_srej(chan, control);
6391 break;
6392 default:
6393 break;
6394 }
6395
6396 if (skb && !skb_in_use) {
6397 BT_DBG("Freeing %p", skb);
6398 kfree_skb(skb);
6399 }
6400
6401 return err;
6402}
6403
6404static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
6405 struct l2cap_ctrl *control,
6406 struct sk_buff *skb, u8 event)
6407{
6408 int err = 0;
6409 u16 txseq = control->txseq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006410 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006411
6412 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6413 event);
6414
6415 switch (event) {
6416 case L2CAP_EV_RECV_IFRAME:
6417 switch (l2cap_classify_txseq(chan, txseq)) {
6418 case L2CAP_TXSEQ_EXPECTED:
6419 /* Keep frame for reassembly later */
6420 l2cap_pass_to_tx(chan, control);
6421 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006422 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006423 BT_DBG("Queued %p (queue len %d)", skb,
6424 skb_queue_len(&chan->srej_q));
6425
6426 chan->expected_tx_seq = __next_seq(chan, txseq);
6427 break;
6428 case L2CAP_TXSEQ_EXPECTED_SREJ:
6429 l2cap_seq_list_pop(&chan->srej_list);
6430
6431 l2cap_pass_to_tx(chan, control);
6432 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006433 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006434 BT_DBG("Queued %p (queue len %d)", skb,
6435 skb_queue_len(&chan->srej_q));
6436
6437 err = l2cap_rx_queued_iframes(chan);
6438 if (err)
6439 break;
6440
6441 break;
6442 case L2CAP_TXSEQ_UNEXPECTED:
6443 /* Got a frame that can't be reassembled yet.
6444 * Save it for later, and send SREJs to cover
6445 * the missing frames.
6446 */
6447 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006448 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006449 BT_DBG("Queued %p (queue len %d)", skb,
6450 skb_queue_len(&chan->srej_q));
6451
6452 l2cap_pass_to_tx(chan, control);
6453 l2cap_send_srej(chan, control->txseq);
6454 break;
6455 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
6456 /* This frame was requested with an SREJ, but
6457 * some expected retransmitted frames are
6458 * missing. Request retransmission of missing
6459 * SREJ'd frames.
6460 */
6461 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02006462 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006463 BT_DBG("Queued %p (queue len %d)", skb,
6464 skb_queue_len(&chan->srej_q));
6465
6466 l2cap_pass_to_tx(chan, control);
6467 l2cap_send_srej_list(chan, control->txseq);
6468 break;
6469 case L2CAP_TXSEQ_DUPLICATE_SREJ:
6470 /* We've already queued this frame. Drop this copy. */
6471 l2cap_pass_to_tx(chan, control);
6472 break;
6473 case L2CAP_TXSEQ_DUPLICATE:
6474 /* Expecting a later sequence number, so this frame
6475 * was already received. Ignore it completely.
6476 */
6477 break;
6478 case L2CAP_TXSEQ_INVALID_IGNORE:
6479 break;
6480 case L2CAP_TXSEQ_INVALID:
6481 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006482 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006483 break;
6484 }
6485 break;
6486 case L2CAP_EV_RECV_RR:
6487 l2cap_pass_to_tx(chan, control);
6488 if (control->final) {
6489 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6490
6491 if (!test_and_clear_bit(CONN_REJ_ACT,
6492 &chan->conn_state)) {
6493 control->final = 0;
6494 l2cap_retransmit_all(chan, control);
6495 }
6496
6497 l2cap_ertm_send(chan);
6498 } else if (control->poll) {
6499 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6500 &chan->conn_state) &&
6501 chan->unacked_frames) {
6502 __set_retrans_timer(chan);
6503 }
6504
6505 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6506 l2cap_send_srej_tail(chan);
6507 } else {
6508 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6509 &chan->conn_state) &&
6510 chan->unacked_frames)
6511 __set_retrans_timer(chan);
6512
6513 l2cap_send_ack(chan);
6514 }
6515 break;
6516 case L2CAP_EV_RECV_RNR:
6517 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6518 l2cap_pass_to_tx(chan, control);
6519 if (control->poll) {
6520 l2cap_send_srej_tail(chan);
6521 } else {
6522 struct l2cap_ctrl rr_control;
6523 memset(&rr_control, 0, sizeof(rr_control));
6524 rr_control.sframe = 1;
6525 rr_control.super = L2CAP_SUPER_RR;
6526 rr_control.reqseq = chan->buffer_seq;
6527 l2cap_send_sframe(chan, &rr_control);
6528 }
6529
6530 break;
6531 case L2CAP_EV_RECV_REJ:
6532 l2cap_handle_rej(chan, control);
6533 break;
6534 case L2CAP_EV_RECV_SREJ:
6535 l2cap_handle_srej(chan, control);
6536 break;
6537 }
6538
6539 if (skb && !skb_in_use) {
6540 BT_DBG("Freeing %p", skb);
6541 kfree_skb(skb);
6542 }
6543
6544 return err;
6545}
6546
Mat Martineau32b32732012-10-23 15:24:11 -07006547static int l2cap_finish_move(struct l2cap_chan *chan)
6548{
6549 BT_DBG("chan %p", chan);
6550
6551 chan->rx_state = L2CAP_RX_STATE_RECV;
6552
6553 if (chan->hs_hcon)
6554 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6555 else
6556 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6557
6558 return l2cap_resegment(chan);
6559}
6560
6561static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6562 struct l2cap_ctrl *control,
6563 struct sk_buff *skb, u8 event)
6564{
6565 int err;
6566
6567 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6568 event);
6569
6570 if (!control->poll)
6571 return -EPROTO;
6572
6573 l2cap_process_reqseq(chan, control->reqseq);
6574
6575 if (!skb_queue_empty(&chan->tx_q))
6576 chan->tx_send_head = skb_peek(&chan->tx_q);
6577 else
6578 chan->tx_send_head = NULL;
6579
6580 /* Rewind next_tx_seq to the point expected
6581 * by the receiver.
6582 */
6583 chan->next_tx_seq = control->reqseq;
6584 chan->unacked_frames = 0;
6585
6586 err = l2cap_finish_move(chan);
6587 if (err)
6588 return err;
6589
6590 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6591 l2cap_send_i_or_rr_or_rnr(chan);
6592
6593 if (event == L2CAP_EV_RECV_IFRAME)
6594 return -EPROTO;
6595
6596 return l2cap_rx_state_recv(chan, control, NULL, event);
6597}
6598
6599static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6600 struct l2cap_ctrl *control,
6601 struct sk_buff *skb, u8 event)
6602{
6603 int err;
6604
6605 if (!control->final)
6606 return -EPROTO;
6607
6608 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6609
6610 chan->rx_state = L2CAP_RX_STATE_RECV;
6611 l2cap_process_reqseq(chan, control->reqseq);
6612
6613 if (!skb_queue_empty(&chan->tx_q))
6614 chan->tx_send_head = skb_peek(&chan->tx_q);
6615 else
6616 chan->tx_send_head = NULL;
6617
6618 /* Rewind next_tx_seq to the point expected
6619 * by the receiver.
6620 */
6621 chan->next_tx_seq = control->reqseq;
6622 chan->unacked_frames = 0;
6623
6624 if (chan->hs_hcon)
6625 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6626 else
6627 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6628
6629 err = l2cap_resegment(chan);
6630
6631 if (!err)
6632 err = l2cap_rx_state_recv(chan, control, skb, event);
6633
6634 return err;
6635}
6636
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006637static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6638{
6639 /* Make sure reqseq is for a packet that has been sent but not acked */
6640 u16 unacked;
6641
6642 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6643 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6644}
6645
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006646static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6647 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006648{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006649 int err = 0;
6650
6651 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6652 control, skb, event, chan->rx_state);
6653
6654 if (__valid_reqseq(chan, control->reqseq)) {
6655 switch (chan->rx_state) {
6656 case L2CAP_RX_STATE_RECV:
6657 err = l2cap_rx_state_recv(chan, control, skb, event);
6658 break;
6659 case L2CAP_RX_STATE_SREJ_SENT:
6660 err = l2cap_rx_state_srej_sent(chan, control, skb,
6661 event);
6662 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006663 case L2CAP_RX_STATE_WAIT_P:
6664 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6665 break;
6666 case L2CAP_RX_STATE_WAIT_F:
6667 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6668 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006669 default:
6670 /* shut it down */
6671 break;
6672 }
6673 } else {
6674 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6675 control->reqseq, chan->next_tx_seq,
6676 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006677 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006678 }
6679
6680 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006681}
6682
6683static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6684 struct sk_buff *skb)
6685{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006686 int err = 0;
6687
6688 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6689 chan->rx_state);
6690
6691 if (l2cap_classify_txseq(chan, control->txseq) ==
6692 L2CAP_TXSEQ_EXPECTED) {
6693 l2cap_pass_to_tx(chan, control);
6694
6695 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6696 __next_seq(chan, chan->buffer_seq));
6697
6698 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6699
6700 l2cap_reassemble_sdu(chan, skb, control);
6701 } else {
6702 if (chan->sdu) {
6703 kfree_skb(chan->sdu);
6704 chan->sdu = NULL;
6705 }
6706 chan->sdu_last_frag = NULL;
6707 chan->sdu_len = 0;
6708
6709 if (skb) {
6710 BT_DBG("Freeing %p", skb);
6711 kfree_skb(skb);
6712 }
6713 }
6714
6715 chan->last_acked_seq = control->txseq;
6716 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6717
6718 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006719}
6720
6721static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6722{
6723 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6724 u16 len;
6725 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006726
Mat Martineaub76bbd62012-04-11 10:48:43 -07006727 __unpack_control(chan, skb);
6728
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006729 len = skb->len;
6730
6731 /*
6732 * We can just drop the corrupted I-frame here.
6733 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006734 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006735 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006736 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006737 goto drop;
6738
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006739 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006740 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006741
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006742 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006743 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006744
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006745 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006746 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006747 goto drop;
6748 }
6749
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006750 if (!control->sframe) {
6751 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006752
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006753 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6754 control->sar, control->reqseq, control->final,
6755 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006756
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006757 /* Validate F-bit - F=0 always valid, F=1 only
6758 * valid in TX WAIT_F
6759 */
6760 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006761 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006762
6763 if (chan->mode != L2CAP_MODE_STREAMING) {
6764 event = L2CAP_EV_RECV_IFRAME;
6765 err = l2cap_rx(chan, control, skb, event);
6766 } else {
6767 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006768 }
6769
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006770 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006771 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006772 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006773 const u8 rx_func_to_event[4] = {
6774 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6775 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6776 };
6777
6778 /* Only I-frames are expected in streaming mode */
6779 if (chan->mode == L2CAP_MODE_STREAMING)
6780 goto drop;
6781
6782 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6783 control->reqseq, control->final, control->poll,
6784 control->super);
6785
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006786 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006787 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006788 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006789 goto drop;
6790 }
6791
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006792 /* Validate F and P bits */
6793 if (control->final && (control->poll ||
6794 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6795 goto drop;
6796
6797 event = rx_func_to_event[control->super];
6798 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006799 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006800 }
6801
6802 return 0;
6803
6804drop:
6805 kfree_skb(skb);
6806 return 0;
6807}
6808
Johan Hedbergb1c325c2013-12-05 09:43:34 +02006809static void l2cap_chan_le_send_credits(struct l2cap_chan *chan)
6810{
6811 struct l2cap_conn *conn = chan->conn;
6812 struct l2cap_le_credits pkt;
6813 u16 return_credits;
6814
6815 /* We return more credits to the sender only after the amount of
6816 * credits falls below half of the initial amount.
6817 */
6818 if (chan->rx_credits >= (L2CAP_LE_MAX_CREDITS + 1) / 2)
6819 return;
6820
6821 return_credits = L2CAP_LE_MAX_CREDITS - chan->rx_credits;
6822
6823 BT_DBG("chan %p returning %u credits to sender", chan, return_credits);
6824
6825 chan->rx_credits += return_credits;
6826
6827 pkt.cid = cpu_to_le16(chan->scid);
6828 pkt.credits = cpu_to_le16(return_credits);
6829
6830 chan->ident = l2cap_get_ident(conn);
6831
6832 l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CREDITS, sizeof(pkt), &pkt);
6833}
6834
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006835static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6836{
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006837 int err;
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006838
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006839 if (!chan->rx_credits) {
6840 BT_ERR("No credits to receive LE L2CAP data");
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006841 return -ENOBUFS;
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006842 }
6843
6844 if (chan->imtu < skb->len) {
6845 BT_ERR("Too big LE L2CAP PDU");
6846 return -ENOBUFS;
6847 }
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006848
6849 chan->rx_credits--;
6850 BT_DBG("rx_credits %u -> %u", chan->rx_credits + 1, chan->rx_credits);
6851
6852 l2cap_chan_le_send_credits(chan);
6853
Johan Hedbergaac23bf2013-06-01 10:14:57 +03006854 err = 0;
6855
6856 if (!chan->sdu) {
6857 u16 sdu_len;
6858
6859 sdu_len = get_unaligned_le16(skb->data);
6860 skb_pull(skb, L2CAP_SDULEN_SIZE);
6861
6862 BT_DBG("Start of new SDU. sdu_len %u skb->len %u imtu %u",
6863 sdu_len, skb->len, chan->imtu);
6864
6865 if (sdu_len > chan->imtu) {
6866 BT_ERR("Too big LE L2CAP SDU length received");
6867 err = -EMSGSIZE;
6868 goto failed;
6869 }
6870
6871 if (skb->len > sdu_len) {
6872 BT_ERR("Too much LE L2CAP data received");
6873 err = -EINVAL;
6874 goto failed;
6875 }
6876
6877 if (skb->len == sdu_len)
6878 return chan->ops->recv(chan, skb);
6879
6880 chan->sdu = skb;
6881 chan->sdu_len = sdu_len;
6882 chan->sdu_last_frag = skb;
6883
6884 return 0;
6885 }
6886
6887 BT_DBG("SDU fragment. chan->sdu->len %u skb->len %u chan->sdu_len %u",
6888 chan->sdu->len, skb->len, chan->sdu_len);
6889
6890 if (chan->sdu->len + skb->len > chan->sdu_len) {
6891 BT_ERR("Too much LE L2CAP data received");
6892 err = -EINVAL;
6893 goto failed;
6894 }
6895
6896 append_skb_frag(chan->sdu, skb, &chan->sdu_last_frag);
6897 skb = NULL;
6898
6899 if (chan->sdu->len == chan->sdu_len) {
6900 err = chan->ops->recv(chan, chan->sdu);
6901 if (!err) {
6902 chan->sdu = NULL;
6903 chan->sdu_last_frag = NULL;
6904 chan->sdu_len = 0;
6905 }
6906 }
6907
6908failed:
6909 if (err) {
6910 kfree_skb(skb);
6911 kfree_skb(chan->sdu);
6912 chan->sdu = NULL;
6913 chan->sdu_last_frag = NULL;
6914 chan->sdu_len = 0;
6915 }
6916
6917 /* We can't return an error here since we took care of the skb
6918 * freeing internally. An error return would cause the caller to
6919 * do a double-free of the skb.
6920 */
6921 return 0;
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006922}
6923
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006924static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6925 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006926{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006927 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006928
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006929 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006930 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006931 if (cid == L2CAP_CID_A2MP) {
6932 chan = a2mp_channel_create(conn, skb);
6933 if (!chan) {
6934 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006935 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006936 }
6937
6938 l2cap_chan_lock(chan);
6939 } else {
6940 BT_DBG("unknown cid 0x%4.4x", cid);
6941 /* Drop packet and return */
6942 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006943 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006944 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006945 }
6946
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006947 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006948
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006949 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006950 goto drop;
6951
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006952 switch (chan->mode) {
Johan Hedberg38319712013-05-17 12:49:23 +03006953 case L2CAP_MODE_LE_FLOWCTL:
Johan Hedbergfad5fc892013-12-05 09:45:01 +02006954 if (l2cap_le_data_rcv(chan, skb) < 0)
6955 goto drop;
6956
6957 goto done;
6958
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006959 case L2CAP_MODE_BASIC:
6960 /* If socket recv buffers overflows we drop data here
6961 * which is *bad* because L2CAP has to be reliable.
6962 * But we don't have any other choice. L2CAP doesn't
6963 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006964
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006965 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006966 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006967
Gustavo Padovan80b98022012-05-27 22:27:51 -03006968 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006969 goto done;
6970 break;
6971
6972 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006973 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006974 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006975 goto done;
6976
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006977 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006978 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006979 break;
6980 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006981
6982drop:
6983 kfree_skb(skb);
6984
6985done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006986 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006987}
6988
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006989static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6990 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006991{
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006992 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006993 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006994
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006995 if (hcon->type != ACL_LINK)
6996 goto drop;
6997
Johan Hedbergbf20fd42013-05-14 13:23:13 +03006998 chan = l2cap_global_chan_by_psm(0, psm, &hcon->src, &hcon->dst,
6999 ACL_LINK);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007000 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007001 goto drop;
7002
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02007003 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007004
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007005 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007006 goto drop;
7007
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03007008 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007009 goto drop;
7010
Marcel Holtmann2edf8702013-10-13 12:55:29 -07007011 /* Store remote BD_ADDR and PSM for msg_name */
Marcel Holtmann06ae3312013-10-18 03:43:00 -07007012 bacpy(&bt_cb(skb)->bdaddr, &hcon->dst);
Marcel Holtmann2edf8702013-10-13 12:55:29 -07007013 bt_cb(skb)->psm = psm;
7014
Gustavo Padovan80b98022012-05-27 22:27:51 -03007015 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03007016 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007017
7018drop:
7019 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007020}
7021
Marcel Holtmann72f78352013-04-23 00:59:00 -07007022static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03007023 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007024{
Marcel Holtmannb99707d2013-10-03 02:54:11 -07007025 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007026 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007027
Marcel Holtmannb99707d2013-10-03 02:54:11 -07007028 if (hcon->type != LE_LINK)
7029 goto drop;
7030
Johan Hedbergaf1c0132013-04-29 19:35:42 +03007031 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann06ae3312013-10-18 03:43:00 -07007032 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007033 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007034 goto drop;
7035
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02007036 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007037
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07007038 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, hcon->dst_type))
7039 goto drop;
7040
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03007041 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007042 goto drop;
7043
Gustavo Padovan80b98022012-05-27 22:27:51 -03007044 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03007045 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007046
7047drop:
7048 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007049}
7050
Linus Torvalds1da177e2005-04-16 15:20:36 -07007051static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
7052{
7053 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07007054 u16 cid, len;
7055 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007056
7057 skb_pull(skb, L2CAP_HDR_SIZE);
7058 cid = __le16_to_cpu(lh->cid);
7059 len = __le16_to_cpu(lh->len);
7060
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03007061 if (len != skb->len) {
7062 kfree_skb(skb);
7063 return;
7064 }
7065
Linus Torvalds1da177e2005-04-16 15:20:36 -07007066 BT_DBG("len %d, cid 0x%4.4x", len, cid);
7067
7068 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03007069 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007070 l2cap_sig_channel(conn, skb);
7071 break;
7072
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03007073 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02007074 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03007075 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007076 l2cap_conless_channel(conn, psm, skb);
7077 break;
7078
Johan Hedberg073d1cf2013-04-29 19:35:35 +03007079 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07007080 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03007081 break;
7082
Marcel Holtmanna2877622013-10-02 23:46:54 -07007083 case L2CAP_CID_LE_SIGNALING:
7084 l2cap_le_sig_channel(conn, skb);
7085 break;
7086
Anderson Brigliab501d6a2011-06-07 18:46:31 -03007087 case L2CAP_CID_SMP:
7088 if (smp_sig_channel(conn, skb))
7089 l2cap_conn_del(conn->hcon, EACCES);
7090 break;
7091
Linus Torvalds1da177e2005-04-16 15:20:36 -07007092 default:
7093 l2cap_data_channel(conn, cid, skb);
7094 break;
7095 }
7096}
7097
7098/* ---- L2CAP interface with lower layer (HCI) ---- */
7099
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007100int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007101{
7102 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007103 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007104
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03007105 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007106
7107 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007108 read_lock(&chan_list_lock);
7109 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007110 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007111 continue;
7112
Marcel Holtmann7eafc592013-10-13 08:12:47 -07007113 if (!bacmp(&c->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007114 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03007115 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007116 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007117 exact++;
Marcel Holtmann7eafc592013-10-13 08:12:47 -07007118 } else if (!bacmp(&c->src, BDADDR_ANY)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007119 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03007120 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01007121 lm2 |= HCI_LM_MASTER;
7122 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007123 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007124 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007125
7126 return exact ? lm1 : lm2;
7127}
7128
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03007129void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007130{
Marcel Holtmann01394182006-07-03 10:02:46 +02007131 struct l2cap_conn *conn;
7132
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03007133 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007134
Linus Torvalds1da177e2005-04-16 15:20:36 -07007135 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03007136 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007137 if (conn)
7138 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02007139 } else {
Joe Perchese1750722011-06-29 18:18:29 -07007140 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02007141 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007142}
7143
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007144int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01007145{
7146 struct l2cap_conn *conn = hcon->l2cap_data;
7147
7148 BT_DBG("hcon %p", hcon);
7149
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007150 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02007151 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01007152 return conn->disc_reason;
7153}
7154
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03007155void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007156{
7157 BT_DBG("hcon %p reason %d", hcon, reason);
7158
Joe Perchese1750722011-06-29 18:18:29 -07007159 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007160}
7161
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007162static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007163{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03007164 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01007165 return;
7166
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007167 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007168 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007169 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007170 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03007171 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007172 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007173 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03007174 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01007175 }
7176}
7177
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007178int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007179{
Marcel Holtmann40be4922008-07-14 20:13:50 +02007180 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03007181 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007182
Marcel Holtmann01394182006-07-03 10:02:46 +02007183 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007184 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02007185
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03007186 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007187
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03007188 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05307189 if (!status && encrypt)
7190 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02007191 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03007192 }
7193
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007194 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007195
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007196 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007197 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007198
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03007199 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
7200 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007201
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03007202 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
7203 l2cap_chan_unlock(chan);
7204 continue;
7205 }
7206
Johan Hedberg073d1cf2013-04-29 19:35:35 +03007207 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007208 if (!status && encrypt) {
7209 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02007210 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007211 }
7212
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007213 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03007214 continue;
7215 }
7216
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02007217 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007218 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01007219 continue;
7220 }
7221
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007222 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01007223 chan->state == BT_CONFIG)) {
Marcel Holtmannd97c8992013-10-14 02:53:54 -07007224 chan->ops->resume(chan);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03007225 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007226 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02007227 continue;
7228 }
7229
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007230 if (chan->state == BT_CONNECT) {
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02007231 if (!status)
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03007232 l2cap_start_connection(chan);
Johan Hedberg6d3c15d2013-12-02 22:13:24 +02007233 else
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007234 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03007235 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007236 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007237 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007238
7239 if (!status) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07007240 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007241 res = L2CAP_CR_PEND;
7242 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08007243 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007244 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02007245 l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007246 res = L2CAP_CR_SUCCESS;
7247 stat = L2CAP_CS_NO_INFO;
7248 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007249 } else {
Gustavo Padovanacdcabf2013-10-21 14:21:39 -02007250 l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08007251 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007252 res = L2CAP_CR_SEC_BLOCK;
7253 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007254 }
7255
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03007256 rsp.scid = cpu_to_le16(chan->dcid);
7257 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03007258 rsp.result = cpu_to_le16(res);
7259 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03007260 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01007261 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07007262
7263 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
7264 res == L2CAP_CR_SUCCESS) {
7265 char buf[128];
7266 set_bit(CONF_REQ_SENT, &chan->conf_state);
7267 l2cap_send_cmd(conn, l2cap_get_ident(conn),
7268 L2CAP_CONF_REQ,
7269 l2cap_build_conf_req(chan, buf),
7270 buf);
7271 chan->num_conf_req++;
7272 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007273 }
7274
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02007275 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007276 }
7277
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02007278 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02007279
Linus Torvalds1da177e2005-04-16 15:20:36 -07007280 return 0;
7281}
7282
Ulisses Furquim686ebf22011-12-21 10:11:33 -02007283int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007284{
7285 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007286 struct l2cap_hdr *hdr;
7287 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007288
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03007289 /* For AMP controller do not create l2cap conn */
7290 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
7291 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007292
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02007293 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03007294 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02007295
7296 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007297 goto drop;
7298
7299 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
7300
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007301 switch (flags) {
7302 case ACL_START:
7303 case ACL_START_NO_FLUSH:
7304 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007305 if (conn->rx_len) {
7306 BT_ERR("Unexpected start frame (len %d)", skb->len);
7307 kfree_skb(conn->rx_skb);
7308 conn->rx_skb = NULL;
7309 conn->rx_len = 0;
7310 l2cap_conn_unreliable(conn, ECOMM);
7311 }
7312
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03007313 /* Start fragment always begin with Basic L2CAP header */
7314 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07007315 BT_ERR("Frame is too short (len %d)", skb->len);
7316 l2cap_conn_unreliable(conn, ECOMM);
7317 goto drop;
7318 }
7319
7320 hdr = (struct l2cap_hdr *) skb->data;
7321 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
7322
7323 if (len == skb->len) {
7324 /* Complete frame received */
7325 l2cap_recv_frame(conn, skb);
7326 return 0;
7327 }
7328
7329 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
7330
7331 if (skb->len > len) {
7332 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01007333 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007334 l2cap_conn_unreliable(conn, ECOMM);
7335 goto drop;
7336 }
7337
7338 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03007339 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03007340 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007341 goto drop;
7342
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03007343 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01007344 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007345 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007346 break;
7347
7348 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07007349 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
7350
7351 if (!conn->rx_len) {
7352 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
7353 l2cap_conn_unreliable(conn, ECOMM);
7354 goto drop;
7355 }
7356
7357 if (skb->len > conn->rx_len) {
7358 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01007359 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007360 kfree_skb(conn->rx_skb);
7361 conn->rx_skb = NULL;
7362 conn->rx_len = 0;
7363 l2cap_conn_unreliable(conn, ECOMM);
7364 goto drop;
7365 }
7366
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03007367 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01007368 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007369 conn->rx_len -= skb->len;
7370
7371 if (!conn->rx_len) {
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02007372 /* Complete frame received. l2cap_recv_frame
7373 * takes ownership of the skb so set the global
7374 * rx_skb pointer to NULL first.
7375 */
7376 struct sk_buff *rx_skb = conn->rx_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007377 conn->rx_skb = NULL;
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02007378 l2cap_recv_frame(conn, rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007379 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03007380 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007381 }
7382
7383drop:
7384 kfree_skb(skb);
7385 return 0;
7386}
7387
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007388static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007389{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007390 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007391
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02007392 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007393
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03007394 list_for_each_entry(c, &chan_list, global_l) {
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03007395 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 -07007396 &c->src, &c->dst,
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03007397 c->state, __le16_to_cpu(c->psm),
7398 c->scid, c->dcid, c->imtu, c->omtu,
7399 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02007400 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07007401
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02007402 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08007403
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007404 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007405}
7406
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007407static int l2cap_debugfs_open(struct inode *inode, struct file *file)
7408{
7409 return single_open(file, l2cap_debugfs_show, inode->i_private);
7410}
7411
7412static const struct file_operations l2cap_debugfs_fops = {
7413 .open = l2cap_debugfs_open,
7414 .read = seq_read,
7415 .llseek = seq_lseek,
7416 .release = single_release,
7417};
7418
7419static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007420
Gustavo F. Padovan64274512011-02-07 20:08:52 -02007421int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007422{
7423 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08007424
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007425 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07007426 if (err < 0)
7427 return err;
7428
Marcel Holtmann1120e4b2013-10-17 17:24:16 -07007429 if (IS_ERR_OR_NULL(bt_debugfs))
7430 return 0;
7431
7432 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
7433 NULL, &l2cap_debugfs_fops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007434
Linus Torvalds1da177e2005-04-16 15:20:36 -07007435 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007436}
7437
Gustavo F. Padovan64274512011-02-07 20:08:52 -02007438void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007439{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01007440 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02007441 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07007442}
7443
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03007444module_param(disable_ertm, bool, 0644);
7445MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");