blob: d52bd0d326217b29f01576eb73de7d334a0a84f3 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
Gustavo F. Padovance5706b2010-07-13 11:57:11 -03004 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
Gustavo F. Padovan5d8868f2010-07-16 16:18:39 -03005 Copyright (C) 2010 Google Inc.
Gustavo F. Padovan590051d2011-12-18 13:39:33 -02006 Copyright (C) 2011 ProFUSION Embedded Systems
Mat Martineau422e9252012-04-27 16:50:55 -07007 Copyright (c) 2012 Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07008
9 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License version 2 as
13 published by the Free Software Foundation;
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
18 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090019 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090024 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
25 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070026 SOFTWARE IS DISCLAIMED.
27*/
28
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020029/* Bluetooth L2CAP core. */
Linus Torvalds1da177e2005-04-16 15:20:36 -070030
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/module.h>
32
Marcel Holtmannaef7d972010-03-21 05:27:45 +010033#include <linux/debugfs.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030034#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36#include <net/bluetooth/bluetooth.h>
37#include <net/bluetooth/hci_core.h>
38#include <net/bluetooth/l2cap.h>
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070039
Marcel Holtmannac4b7232013-10-10 14:54:16 -070040#include "smp.h"
Marcel Holtmann70247282013-10-10 14:54:15 -070041#include "a2mp.h"
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070042#include "amp.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
Mat Martineaud1de6d42012-05-17 20:53:55 -070044bool disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020045
Marcel Holtmann547d1032013-10-12 08:18:19 -070046static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN | L2CAP_FEAT_UCD;
Marcel Holtmannd40bffb2013-10-12 08:18:18 -070047static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP | L2CAP_FC_CONNLESS, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
Johannes Bergb5ad8b72011-06-01 08:54:45 +020049static LIST_HEAD(chan_list);
50static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
Linus Torvalds1da177e2005-04-16 15:20:36 -070052static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +010053 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030054static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
Gustavo Padovan2d792812012-10-06 10:07:01 +010055 void *data);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -030056static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +020057static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
Gustavo Padovand6603662012-05-21 13:58:22 -030059static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
Gustavo Padovan2d792812012-10-06 10:07:01 +010060 struct sk_buff_head *skbs, u8 event);
Mat Martineau608bcc62012-05-17 20:53:32 -070061
Marcel Holtmann4f1654e2013-10-13 08:50:41 -070062static inline __u8 bdaddr_type(struct hci_conn *hcon, __u8 type)
63{
64 if (hcon->type == LE_LINK) {
65 if (type == ADDR_LE_DEV_PUBLIC)
66 return BDADDR_LE_PUBLIC;
67 else
68 return BDADDR_LE_RANDOM;
69 }
70
71 return BDADDR_BREDR;
72}
73
Marcel Holtmann01394182006-07-03 10:02:46 +020074/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030075
Gustavo Padovan2d792812012-10-06 10:07:01 +010076static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
77 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020078{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020079 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030080
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020081 list_for_each_entry(c, &conn->chan_l, list) {
82 if (c->dcid == cid)
83 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020084 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020085 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020086}
87
Gustavo Padovan2d792812012-10-06 10:07:01 +010088static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
89 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020090{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020091 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030092
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020093 list_for_each_entry(c, &conn->chan_l, list) {
94 if (c->scid == cid)
95 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020096 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020097 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020098}
99
100/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -0700101 * Returns locked channel. */
Gustavo Padovan2d792812012-10-06 10:07:01 +0100102static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
103 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +0200104{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300105 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300106
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200107 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300108 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -0700109 if (c)
110 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200111 mutex_unlock(&conn->chan_lock);
112
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300113 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200114}
115
Mat Martineaub1a130b2012-10-23 15:24:09 -0700116/* Find channel with given DCID.
117 * Returns locked channel.
118 */
119static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
120 u16 cid)
121{
122 struct l2cap_chan *c;
123
124 mutex_lock(&conn->chan_lock);
125 c = __l2cap_get_chan_by_dcid(conn, cid);
126 if (c)
127 l2cap_chan_lock(c);
128 mutex_unlock(&conn->chan_lock);
129
130 return c;
131}
132
Gustavo Padovan2d792812012-10-06 10:07:01 +0100133static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
134 u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200135{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200136 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300137
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200138 list_for_each_entry(c, &conn->chan_l, list) {
139 if (c->ident == ident)
140 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200141 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200142 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200143}
144
Mat Martineau5b155ef2012-10-23 15:24:14 -0700145static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
146 u8 ident)
147{
148 struct l2cap_chan *c;
149
150 mutex_lock(&conn->chan_lock);
151 c = __l2cap_get_chan_by_ident(conn, ident);
152 if (c)
153 l2cap_chan_lock(c);
154 mutex_unlock(&conn->chan_lock);
155
156 return c;
157}
158
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300159static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300160{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300161 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300162
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300163 list_for_each_entry(c, &chan_list, global_l) {
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700164 if (c->sport == psm && !bacmp(&c->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100165 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300166 }
Szymon Janc250938c2011-11-16 09:32:22 +0100167 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300168}
169
170int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
171{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300172 int err;
173
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200174 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300175
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300176 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300177 err = -EADDRINUSE;
178 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300179 }
180
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300181 if (psm) {
182 chan->psm = psm;
183 chan->sport = psm;
184 err = 0;
185 } else {
186 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300187
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300188 err = -EINVAL;
189 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300190 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300191 chan->psm = cpu_to_le16(p);
192 chan->sport = cpu_to_le16(p);
193 err = 0;
194 break;
195 }
196 }
197
198done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200199 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300200 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300201}
202
203int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
204{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200205 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300206
207 chan->scid = scid;
208
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200209 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300210
211 return 0;
212}
213
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300214static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200215{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300216 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200217
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300218 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300219 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200220 return cid;
221 }
222
223 return 0;
224}
225
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200226static void __l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300227{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200228 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100229 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200230
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300231 chan->state = state;
Gustavo Padovan53f52122013-10-15 19:24:45 -0300232 chan->ops->state_change(chan, state, 0);
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300233}
234
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200235static void l2cap_state_change(struct l2cap_chan *chan, int state)
236{
237 struct sock *sk = chan->sk;
238
239 lock_sock(sk);
240 __l2cap_state_change(chan, state);
241 release_sock(sk);
242}
243
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300244static inline void l2cap_state_change_and_error(struct l2cap_chan *chan,
245 int state, int err)
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200246{
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300247 struct sock *sk = chan->sk;
248
249 lock_sock(sk);
250 chan->state = state;
Gustavo Padovan53f52122013-10-15 19:24:45 -0300251 chan->ops->state_change(chan, chan->state, err);
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300252 release_sock(sk);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200253}
254
255static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
256{
257 struct sock *sk = chan->sk;
258
259 lock_sock(sk);
Gustavo Padovanf8e73012013-10-15 19:24:46 -0300260 chan->ops->state_change(chan, chan->state, err);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200261 release_sock(sk);
262}
263
Mat Martineau4239d162012-05-17 20:53:49 -0700264static void __set_retrans_timer(struct l2cap_chan *chan)
265{
266 if (!delayed_work_pending(&chan->monitor_timer) &&
267 chan->retrans_timeout) {
268 l2cap_set_timer(chan, &chan->retrans_timer,
269 msecs_to_jiffies(chan->retrans_timeout));
270 }
271}
272
273static void __set_monitor_timer(struct l2cap_chan *chan)
274{
275 __clear_retrans_timer(chan);
276 if (chan->monitor_timeout) {
277 l2cap_set_timer(chan, &chan->monitor_timer,
278 msecs_to_jiffies(chan->monitor_timeout));
279 }
280}
281
Mat Martineau608bcc62012-05-17 20:53:32 -0700282static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
283 u16 seq)
284{
285 struct sk_buff *skb;
286
287 skb_queue_walk(head, skb) {
288 if (bt_cb(skb)->control.txseq == seq)
289 return skb;
290 }
291
292 return NULL;
293}
294
Mat Martineau3c588192012-04-11 10:48:42 -0700295/* ---- L2CAP sequence number lists ---- */
296
297/* For ERTM, ordered lists of sequence numbers must be tracked for
298 * SREJ requests that are received and for frames that are to be
299 * retransmitted. These seq_list functions implement a singly-linked
300 * list in an array, where membership in the list can also be checked
301 * in constant time. Items can also be added to the tail of the list
302 * and removed from the head in constant time, without further memory
303 * allocs or frees.
304 */
305
306static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
307{
308 size_t alloc_size, i;
309
310 /* Allocated size is a power of 2 to map sequence numbers
311 * (which may be up to 14 bits) in to a smaller array that is
312 * sized for the negotiated ERTM transmit windows.
313 */
314 alloc_size = roundup_pow_of_two(size);
315
316 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
317 if (!seq_list->list)
318 return -ENOMEM;
319
320 seq_list->mask = alloc_size - 1;
321 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
322 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
323 for (i = 0; i < alloc_size; i++)
324 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
325
326 return 0;
327}
328
329static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
330{
331 kfree(seq_list->list);
332}
333
334static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
335 u16 seq)
336{
337 /* Constant-time check for list membership */
338 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
339}
340
341static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
342{
343 u16 mask = seq_list->mask;
344
345 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
346 /* In case someone tries to pop the head of an empty list */
347 return L2CAP_SEQ_LIST_CLEAR;
348 } else if (seq_list->head == seq) {
349 /* Head can be removed in constant time */
350 seq_list->head = seq_list->list[seq & mask];
351 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
352
353 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
354 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
355 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
356 }
357 } else {
358 /* Walk the list to find the sequence number */
359 u16 prev = seq_list->head;
360 while (seq_list->list[prev & mask] != seq) {
361 prev = seq_list->list[prev & mask];
362 if (prev == L2CAP_SEQ_LIST_TAIL)
363 return L2CAP_SEQ_LIST_CLEAR;
364 }
365
366 /* Unlink the number from the list and clear it */
367 seq_list->list[prev & mask] = seq_list->list[seq & mask];
368 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
369 if (seq_list->tail == seq)
370 seq_list->tail = prev;
371 }
372 return seq;
373}
374
375static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
376{
377 /* Remove the head in constant time */
378 return l2cap_seq_list_remove(seq_list, seq_list->head);
379}
380
381static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
382{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300383 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700384
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300385 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
386 return;
387
388 for (i = 0; i <= seq_list->mask; i++)
389 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
390
391 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
392 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700393}
394
395static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
396{
397 u16 mask = seq_list->mask;
398
399 /* All appends happen in constant time */
400
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300401 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
402 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700403
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300404 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
405 seq_list->head = seq;
406 else
407 seq_list->list[seq_list->tail & mask] = seq;
408
409 seq_list->tail = seq;
410 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700411}
412
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300413static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300414{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300415 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100416 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200417 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300418 int reason;
419
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200420 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300421
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200422 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200423 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300424
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300425 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300426 reason = ECONNREFUSED;
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300427 else if (chan->state == BT_CONNECT &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100428 chan->sec_level != BT_SECURITY_SDP)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300429 reason = ECONNREFUSED;
430 else
431 reason = ETIMEDOUT;
432
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300433 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300434
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200435 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300436
Gustavo Padovan80b98022012-05-27 22:27:51 -0300437 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200438 mutex_unlock(&conn->chan_lock);
439
Ulisses Furquim371fd832011-12-21 20:02:36 -0200440 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300441}
442
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300443struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200444{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300445 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200446
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300447 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
448 if (!chan)
449 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200450
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200451 mutex_init(&chan->lock);
452
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200453 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300454 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200455 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300456
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300457 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300458
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300459 chan->state = BT_OPEN;
460
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530461 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300462
Mat Martineau28270112012-05-17 21:14:09 -0700463 /* This flag is cleared in l2cap_chan_ready() */
464 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
465
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300466 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100467
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300468 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200469}
470
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530471static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300472{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530473 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
474
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530475 BT_DBG("chan %p", chan);
476
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200477 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300478 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200479 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300480
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530481 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300482}
483
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530484void l2cap_chan_hold(struct l2cap_chan *c)
485{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530486 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530487
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530488 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530489}
490
491void l2cap_chan_put(struct l2cap_chan *c)
492{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530493 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530494
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530495 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530496}
497
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300498void l2cap_chan_set_defaults(struct l2cap_chan *chan)
499{
500 chan->fcs = L2CAP_FCS_CRC16;
501 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
502 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
503 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700504 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300505 chan->sec_level = BT_SECURITY_LOW;
506
507 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
508}
509
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300510void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200511{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300512 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200513 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200514
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200515 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100516
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300517 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200518
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200519 switch (chan->chan_type) {
520 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300521 if (conn->hcon->type == LE_LINK) {
522 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300523 chan->omtu = L2CAP_DEFAULT_MTU;
Johan Hedberg9f22398c2013-04-29 19:35:38 +0300524 if (chan->dcid == L2CAP_CID_ATT)
525 chan->scid = L2CAP_CID_ATT;
526 else
527 chan->scid = l2cap_alloc_cid(conn);
Ville Tervob62f3282011-02-10 22:38:50 -0300528 } else {
529 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300530 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300531 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300532 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200533 break;
534
535 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200536 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300537 chan->scid = L2CAP_CID_CONN_LESS;
538 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300539 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200540 break;
541
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300542 case L2CAP_CHAN_CONN_FIX_A2MP:
543 chan->scid = L2CAP_CID_A2MP;
544 chan->dcid = L2CAP_CID_A2MP;
545 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
546 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
547 break;
548
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200549 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200550 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300551 chan->scid = L2CAP_CID_SIGNALING;
552 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300553 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200554 }
555
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300556 chan->local_id = L2CAP_BESTEFFORT_ID;
557 chan->local_stype = L2CAP_SERV_BESTEFFORT;
558 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
559 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
560 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300561 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300562
Ulisses Furquim371fd832011-12-21 20:02:36 -0200563 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300564
Johan Hedberg5ee98912013-04-29 19:35:43 +0300565 hci_conn_hold(conn->hcon);
566
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200567 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200568}
569
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300570void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200571{
572 mutex_lock(&conn->chan_lock);
573 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200574 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200575}
576
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300577void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200578{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300579 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200580
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300581 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200582
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300583 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200584
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900585 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300586 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300587 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200588 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200589
Ulisses Furquim371fd832011-12-21 20:02:36 -0200590 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300591
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300592 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300593
594 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
David Herrmann76a68ba2013-04-06 20:28:37 +0200595 hci_conn_drop(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300596
597 if (mgr && mgr->bredr_chan == chan)
598 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200599 }
600
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200601 if (chan->hs_hchan) {
602 struct hci_chan *hs_hchan = chan->hs_hchan;
603
604 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
605 amp_disconnect_logical_link(hs_hchan);
606 }
607
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100608 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200609
Mat Martineau28270112012-05-17 21:14:09 -0700610 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300611 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300612
Gustavo Padovanee556f62012-05-18 20:22:38 -0300613 switch(chan->mode) {
614 case L2CAP_MODE_BASIC:
615 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300616
Gustavo Padovanee556f62012-05-18 20:22:38 -0300617 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300618 __clear_retrans_timer(chan);
619 __clear_monitor_timer(chan);
620 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300621
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300622 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300623
Mat Martineau3c588192012-04-11 10:48:42 -0700624 l2cap_seq_list_free(&chan->srej_list);
625 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300626
627 /* fall through */
628
629 case L2CAP_MODE_STREAMING:
630 skb_queue_purge(&chan->tx_q);
631 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300632 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300633
634 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200635}
636
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300637void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300638{
639 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300640
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700641 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300642
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300643 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300644 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100645 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300646 break;
647
648 case BT_CONNECTED:
649 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300650 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100651 conn->hcon->type == ACL_LINK) {
Gustavo Padovan8d836d72013-10-15 19:24:47 -0300652 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200653 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300654 } else
655 l2cap_chan_del(chan, reason);
656 break;
657
658 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300659 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100660 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300661 struct l2cap_conn_rsp rsp;
662 __u16 result;
663
Marcel Holtmannbdc25782013-10-14 02:45:34 -0700664 if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300665 result = L2CAP_CR_SEC_BLOCK;
666 else
667 result = L2CAP_CR_BAD_PSM;
Marcel Holtmannbdc25782013-10-14 02:45:34 -0700668
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300669 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300670
671 rsp.scid = cpu_to_le16(chan->dcid);
672 rsp.dcid = cpu_to_le16(chan->scid);
673 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300674 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300675 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100676 sizeof(rsp), &rsp);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300677 }
678
679 l2cap_chan_del(chan, reason);
680 break;
681
682 case BT_CONNECT:
683 case BT_DISCONN:
684 l2cap_chan_del(chan, reason);
685 break;
686
687 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100688 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300689 break;
690 }
691}
692
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300693static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530694{
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700695 switch (chan->chan_type) {
696 case L2CAP_CHAN_RAW:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300697 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530698 case BT_SECURITY_HIGH:
699 return HCI_AT_DEDICATED_BONDING_MITM;
700 case BT_SECURITY_MEDIUM:
701 return HCI_AT_DEDICATED_BONDING;
702 default:
703 return HCI_AT_NO_BONDING;
704 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700705 break;
Marcel Holtmann3124b842013-10-12 07:19:32 -0700706 case L2CAP_CHAN_CONN_LESS:
707 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_3DSP)) {
708 if (chan->sec_level == BT_SECURITY_LOW)
709 chan->sec_level = BT_SECURITY_SDP;
710 }
711 if (chan->sec_level == BT_SECURITY_HIGH)
712 return HCI_AT_NO_BONDING_MITM;
713 else
714 return HCI_AT_NO_BONDING;
715 break;
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700716 case L2CAP_CHAN_CONN_ORIENTED:
717 if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
718 if (chan->sec_level == BT_SECURITY_LOW)
719 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530720
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700721 if (chan->sec_level == BT_SECURITY_HIGH)
722 return HCI_AT_NO_BONDING_MITM;
723 else
724 return HCI_AT_NO_BONDING;
725 }
726 /* fall through */
727 default:
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300728 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530729 case BT_SECURITY_HIGH:
730 return HCI_AT_GENERAL_BONDING_MITM;
731 case BT_SECURITY_MEDIUM:
732 return HCI_AT_GENERAL_BONDING;
733 default:
734 return HCI_AT_NO_BONDING;
735 }
Marcel Holtmann6a974b52013-10-12 07:19:31 -0700736 break;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530737 }
738}
739
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200740/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200741int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200742{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300743 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100744 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200745
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300746 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100747
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300748 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200749}
750
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200751static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200752{
753 u8 id;
754
755 /* Get next available identificator.
756 * 1 - 128 are used by kernel.
757 * 129 - 199 are reserved.
758 * 200 - 254 are used by utilities like l2ping, etc.
759 */
760
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200761 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200762
763 if (++conn->tx_ident > 128)
764 conn->tx_ident = 1;
765
766 id = conn->tx_ident;
767
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200768 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200769
770 return id;
771}
772
Gustavo Padovan2d792812012-10-06 10:07:01 +0100773static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
774 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200775{
776 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200777 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200778
779 BT_DBG("code 0x%2.2x", code);
780
781 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300782 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200783
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200784 if (lmp_no_flush_capable(conn->hcon->hdev))
785 flags = ACL_START_NO_FLUSH;
786 else
787 flags = ACL_START;
788
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700789 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200790 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700791
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200792 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200793}
794
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700795static bool __chan_is_moving(struct l2cap_chan *chan)
796{
797 return chan->move_state != L2CAP_MOVE_STABLE &&
798 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
799}
800
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200801static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
802{
803 struct hci_conn *hcon = chan->conn->hcon;
804 u16 flags;
805
806 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100807 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200808
Mat Martineaud5f8a752012-10-23 15:24:18 -0700809 if (chan->hs_hcon && !__chan_is_moving(chan)) {
810 if (chan->hs_hchan)
811 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
812 else
813 kfree_skb(skb);
814
815 return;
816 }
817
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200818 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100819 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200820 flags = ACL_START_NO_FLUSH;
821 else
822 flags = ACL_START;
823
824 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
825 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826}
827
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700828static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
829{
830 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
831 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
832
833 if (enh & L2CAP_CTRL_FRAME_TYPE) {
834 /* S-Frame */
835 control->sframe = 1;
836 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
837 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
838
839 control->sar = 0;
840 control->txseq = 0;
841 } else {
842 /* I-Frame */
843 control->sframe = 0;
844 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
845 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
846
847 control->poll = 0;
848 control->super = 0;
849 }
850}
851
852static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
853{
854 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
855 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
856
857 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
858 /* S-Frame */
859 control->sframe = 1;
860 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
861 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
862
863 control->sar = 0;
864 control->txseq = 0;
865 } else {
866 /* I-Frame */
867 control->sframe = 0;
868 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
869 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
870
871 control->poll = 0;
872 control->super = 0;
873 }
874}
875
876static inline void __unpack_control(struct l2cap_chan *chan,
877 struct sk_buff *skb)
878{
879 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
880 __unpack_extended_control(get_unaligned_le32(skb->data),
881 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700882 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700883 } else {
884 __unpack_enhanced_control(get_unaligned_le16(skb->data),
885 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700886 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700887 }
888}
889
890static u32 __pack_extended_control(struct l2cap_ctrl *control)
891{
892 u32 packed;
893
894 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
895 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
896
897 if (control->sframe) {
898 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
899 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
900 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
901 } else {
902 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
903 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
904 }
905
906 return packed;
907}
908
909static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
910{
911 u16 packed;
912
913 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
914 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
915
916 if (control->sframe) {
917 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
918 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
919 packed |= L2CAP_CTRL_FRAME_TYPE;
920 } else {
921 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
922 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
923 }
924
925 return packed;
926}
927
928static inline void __pack_control(struct l2cap_chan *chan,
929 struct l2cap_ctrl *control,
930 struct sk_buff *skb)
931{
932 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
933 put_unaligned_le32(__pack_extended_control(control),
934 skb->data + L2CAP_HDR_SIZE);
935 } else {
936 put_unaligned_le16(__pack_enhanced_control(control),
937 skb->data + L2CAP_HDR_SIZE);
938 }
939}
940
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300941static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
942{
943 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
944 return L2CAP_EXT_HDR_SIZE;
945 else
946 return L2CAP_ENH_HDR_SIZE;
947}
948
Mat Martineaua67d7f62012-05-17 20:53:35 -0700949static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
950 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300951{
952 struct sk_buff *skb;
953 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300954 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300955
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300956 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300957 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300958
Mat Martineaua67d7f62012-05-17 20:53:35 -0700959 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300960
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300961 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700962 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300963
964 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300965 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300966 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300967
Mat Martineaua67d7f62012-05-17 20:53:35 -0700968 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
969 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
970 else
971 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300972
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300973 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700974 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300975 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300976 }
977
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200978 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700979 return skb;
980}
981
982static void l2cap_send_sframe(struct l2cap_chan *chan,
983 struct l2cap_ctrl *control)
984{
985 struct sk_buff *skb;
986 u32 control_field;
987
988 BT_DBG("chan %p, control %p", chan, control);
989
990 if (!control->sframe)
991 return;
992
Mat Martineaub99e13a2012-10-23 15:24:19 -0700993 if (__chan_is_moving(chan))
994 return;
995
Mat Martineaua67d7f62012-05-17 20:53:35 -0700996 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
997 !control->poll)
998 control->final = 1;
999
1000 if (control->super == L2CAP_SUPER_RR)
1001 clear_bit(CONN_RNR_SENT, &chan->conn_state);
1002 else if (control->super == L2CAP_SUPER_RNR)
1003 set_bit(CONN_RNR_SENT, &chan->conn_state);
1004
1005 if (control->super != L2CAP_SUPER_SREJ) {
1006 chan->last_acked_seq = control->reqseq;
1007 __clear_ack_timer(chan);
1008 }
1009
1010 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
1011 control->final, control->poll, control->super);
1012
1013 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1014 control_field = __pack_extended_control(control);
1015 else
1016 control_field = __pack_enhanced_control(control);
1017
1018 skb = l2cap_create_sframe_pdu(chan, control_field);
1019 if (!IS_ERR(skb))
1020 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001021}
1022
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001023static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001024{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001025 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001026
Mat Martineauc9e3d5e2012-05-17 20:53:48 -07001027 BT_DBG("chan %p, poll %d", chan, poll);
1028
1029 memset(&control, 0, sizeof(control));
1030 control.sframe = 1;
1031 control.poll = poll;
1032
1033 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
1034 control.super = L2CAP_SUPER_RNR;
1035 else
1036 control.super = L2CAP_SUPER_RR;
1037
1038 control.reqseq = chan->buffer_seq;
1039 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001040}
1041
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001042static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001043{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001044 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001045}
1046
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001047static bool __amp_capable(struct l2cap_chan *chan)
1048{
1049 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001050 struct hci_dev *hdev;
1051 bool amp_available = false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001052
Marcel Holtmann1df7b172013-10-05 11:47:49 -07001053 if (!conn->hs_enabled)
1054 return false;
1055
1056 if (!(conn->fixed_chan_mask & L2CAP_FC_A2MP))
1057 return false;
1058
1059 read_lock(&hci_dev_list_lock);
1060 list_for_each_entry(hdev, &hci_dev_list, list) {
1061 if (hdev->amp_type != AMP_TYPE_BREDR &&
1062 test_bit(HCI_UP, &hdev->flags)) {
1063 amp_available = true;
1064 break;
1065 }
1066 }
1067 read_unlock(&hci_dev_list_lock);
1068
1069 if (chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED)
1070 return amp_available;
Marcel Holtmann848566b2013-10-01 22:59:22 -07001071
1072 return false;
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001073}
1074
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001075static bool l2cap_check_efs(struct l2cap_chan *chan)
1076{
1077 /* Check EFS parameters */
1078 return true;
1079}
1080
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001081void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001082{
1083 struct l2cap_conn *conn = chan->conn;
1084 struct l2cap_conn_req req;
1085
1086 req.scid = cpu_to_le16(chan->scid);
1087 req.psm = chan->psm;
1088
1089 chan->ident = l2cap_get_ident(conn);
1090
1091 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1092
1093 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1094}
1095
Mat Martineau8eb200b2012-10-23 15:24:17 -07001096static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1097{
1098 struct l2cap_create_chan_req req;
1099 req.scid = cpu_to_le16(chan->scid);
1100 req.psm = chan->psm;
1101 req.amp_id = amp_id;
1102
1103 chan->ident = l2cap_get_ident(chan->conn);
1104
1105 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1106 sizeof(req), &req);
1107}
1108
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001109static void l2cap_move_setup(struct l2cap_chan *chan)
1110{
1111 struct sk_buff *skb;
1112
1113 BT_DBG("chan %p", chan);
1114
1115 if (chan->mode != L2CAP_MODE_ERTM)
1116 return;
1117
1118 __clear_retrans_timer(chan);
1119 __clear_monitor_timer(chan);
1120 __clear_ack_timer(chan);
1121
1122 chan->retry_count = 0;
1123 skb_queue_walk(&chan->tx_q, skb) {
1124 if (bt_cb(skb)->control.retries)
1125 bt_cb(skb)->control.retries = 1;
1126 else
1127 break;
1128 }
1129
1130 chan->expected_tx_seq = chan->buffer_seq;
1131
1132 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1133 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1134 l2cap_seq_list_clear(&chan->retrans_list);
1135 l2cap_seq_list_clear(&chan->srej_list);
1136 skb_queue_purge(&chan->srej_q);
1137
1138 chan->tx_state = L2CAP_TX_STATE_XMIT;
1139 chan->rx_state = L2CAP_RX_STATE_MOVE;
1140
1141 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1142}
1143
Mat Martineau5f3847a2012-10-23 15:24:12 -07001144static void l2cap_move_done(struct l2cap_chan *chan)
1145{
1146 u8 move_role = chan->move_role;
1147 BT_DBG("chan %p", chan);
1148
1149 chan->move_state = L2CAP_MOVE_STABLE;
1150 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1151
1152 if (chan->mode != L2CAP_MODE_ERTM)
1153 return;
1154
1155 switch (move_role) {
1156 case L2CAP_MOVE_ROLE_INITIATOR:
1157 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1158 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1159 break;
1160 case L2CAP_MOVE_ROLE_RESPONDER:
1161 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1162 break;
1163 }
1164}
1165
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001166static void l2cap_chan_ready(struct l2cap_chan *chan)
1167{
Mat Martineau28270112012-05-17 21:14:09 -07001168 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001169 chan->conf_state = 0;
1170 __clear_chan_timer(chan);
1171
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001172 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001173
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001174 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001175}
1176
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001177static void l2cap_start_connection(struct l2cap_chan *chan)
1178{
1179 if (__amp_capable(chan)) {
1180 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1181 a2mp_discover_amp(chan);
1182 } else {
1183 l2cap_send_conn_req(chan);
1184 }
1185}
1186
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001187static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001188{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001189 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001190
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001191 if (conn->hcon->type == LE_LINK) {
1192 l2cap_chan_ready(chan);
1193 return;
1194 }
1195
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001196 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001197 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1198 return;
1199
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001200 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001201 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001202 l2cap_start_connection(chan);
1203 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001204 } else {
1205 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001206 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001207
1208 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1209 conn->info_ident = l2cap_get_ident(conn);
1210
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001211 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001212
Gustavo Padovan2d792812012-10-06 10:07:01 +01001213 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1214 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001215 }
1216}
1217
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001218static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1219{
1220 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001221 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001222 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1223
1224 switch (mode) {
1225 case L2CAP_MODE_ERTM:
1226 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1227 case L2CAP_MODE_STREAMING:
1228 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1229 default:
1230 return 0x00;
1231 }
1232}
1233
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001234static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001235{
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001236 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001237 struct l2cap_disconn_req req;
1238
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001239 if (!conn)
1240 return;
1241
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001242 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001243 __clear_retrans_timer(chan);
1244 __clear_monitor_timer(chan);
1245 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001246 }
1247
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001248 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001249 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001250 return;
1251 }
1252
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001253 req.dcid = cpu_to_le16(chan->dcid);
1254 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001255 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1256 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001257
Gustavo Padovanf8e73012013-10-15 19:24:46 -03001258 l2cap_state_change_and_error(chan, BT_DISCONN, err);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001259}
1260
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001262static void l2cap_conn_start(struct l2cap_conn *conn)
1263{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001264 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001265
1266 BT_DBG("conn %p", conn);
1267
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001268 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001269
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001270 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001271 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001272
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001273 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001274 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001275 continue;
1276 }
1277
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001278 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001279 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001280 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001281 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001282 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001283 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001284
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001285 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001286 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001287 &chan->conf_state)) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001288 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001289 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001290 continue;
1291 }
1292
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001293 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001294
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001295 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001296 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001297 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001298 rsp.scid = cpu_to_le16(chan->dcid);
1299 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001300
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001301 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07001302 struct sock *sk = chan->sk;
1303
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001304 lock_sock(sk);
Marcel Holtmannbdc25782013-10-14 02:45:34 -07001305 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001306 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1307 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001308 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001309
1310 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001311 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001312 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1313 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001314 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001315 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001316 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001317 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1318 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001319 }
1320
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001321 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001322 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001323
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001324 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001325 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001326 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001327 continue;
1328 }
1329
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001330 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001331 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001332 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001333 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001334 }
1335
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001336 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001337 }
1338
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001339 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001340}
1341
Ido Yarivc2287682012-04-20 15:46:07 -03001342/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001343 * Returns closest match, locked.
1344 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001345static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001346 bdaddr_t *src,
1347 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001348{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001349 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001350
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001351 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001352
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001353 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001354 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001355 continue;
1356
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001357 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001358 int src_match, dst_match;
1359 int src_any, dst_any;
1360
Ville Tervob62f3282011-02-10 22:38:50 -03001361 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001362 src_match = !bacmp(&c->src, src);
1363 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001364 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001365 read_unlock(&chan_list_lock);
1366 return c;
1367 }
Ville Tervob62f3282011-02-10 22:38:50 -03001368
1369 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001370 src_any = !bacmp(&c->src, BDADDR_ANY);
1371 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001372 if ((src_match && dst_any) || (src_any && dst_match) ||
1373 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001374 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001375 }
1376 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001377
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001378 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001379
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001380 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001381}
1382
1383static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1384{
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001385 struct hci_conn *hcon = conn->hcon;
Johan Hedberg60bac1842013-04-29 19:35:41 +03001386 struct sock *parent;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001387 struct l2cap_chan *chan, *pchan;
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001388 u8 dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001389
1390 BT_DBG("");
1391
1392 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001393 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001394 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001395 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001396 return;
1397
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001398 /* Client ATT sockets should override the server one */
1399 if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
1400 return;
1401
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001402 dst_type = bdaddr_type(hcon, hcon->dst_type);
1403
1404 /* If device is blocked, do not create a channel for it */
1405 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, dst_type))
1406 return;
1407
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001408 parent = pchan->sk;
1409
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001410 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001411
Gustavo Padovan80b98022012-05-27 22:27:51 -03001412 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001413 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001414 goto clean;
1415
Johan Hedberg9f22398c2013-04-29 19:35:38 +03001416 chan->dcid = L2CAP_CID_ATT;
1417
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07001418 bacpy(&chan->src, &hcon->src);
1419 bacpy(&chan->dst, &hcon->dst);
1420 chan->src_type = bdaddr_type(hcon, hcon->src_type);
1421 chan->dst_type = dst_type;
Ville Tervob62f3282011-02-10 22:38:50 -03001422
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001423 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001424
Ville Tervob62f3282011-02-10 22:38:50 -03001425clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001426 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001427}
1428
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001429static void l2cap_conn_ready(struct l2cap_conn *conn)
1430{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001431 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001432 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001433
1434 BT_DBG("conn %p", conn);
1435
Johan Hedbergd8729922013-04-29 19:35:39 +03001436 /* For outgoing pairing which doesn't necessarily have an
1437 * associated socket (e.g. mgmt_pair_device).
1438 */
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001439 if (hcon->out && hcon->type == LE_LINK)
1440 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001441
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001442 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001443
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001444 if (hcon->type == LE_LINK)
1445 l2cap_le_conn_ready(conn);
1446
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001447 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001448
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001449 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001450
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001451 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1452 l2cap_chan_unlock(chan);
1453 continue;
1454 }
1455
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001456 if (hcon->type == LE_LINK) {
1457 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001458 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001459
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001460 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo Padovan74e75742013-10-15 19:24:51 -03001461 l2cap_chan_ready(chan);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001462
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001463 } else if (chan->state == BT_CONNECT) {
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001464 l2cap_do_start(chan);
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001465 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001466
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001467 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001468 }
1469
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001470 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001471}
1472
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001473/* Notify sockets that we cannot guaranty reliability anymore */
1474static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1475{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001476 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001477
1478 BT_DBG("conn %p", conn);
1479
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001480 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001481
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001482 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001483 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001484 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001485 }
1486
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001487 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001488}
1489
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001490static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001491{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001492 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001493 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001494
Marcel Holtmann984947d2009-02-06 23:35:19 +01001495 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001496 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001497
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001498 l2cap_conn_start(conn);
1499}
1500
David Herrmann2c8e1412013-04-06 20:28:45 +02001501/*
1502 * l2cap_user
1503 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1504 * callback is called during registration. The ->remove callback is called
1505 * during unregistration.
1506 * An l2cap_user object can either be explicitly unregistered or when the
1507 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1508 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1509 * External modules must own a reference to the l2cap_conn object if they intend
1510 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1511 * any time if they don't.
1512 */
1513
1514int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1515{
1516 struct hci_dev *hdev = conn->hcon->hdev;
1517 int ret;
1518
1519 /* We need to check whether l2cap_conn is registered. If it is not, we
1520 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1521 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1522 * relies on the parent hci_conn object to be locked. This itself relies
1523 * on the hci_dev object to be locked. So we must lock the hci device
1524 * here, too. */
1525
1526 hci_dev_lock(hdev);
1527
1528 if (user->list.next || user->list.prev) {
1529 ret = -EINVAL;
1530 goto out_unlock;
1531 }
1532
1533 /* conn->hchan is NULL after l2cap_conn_del() was called */
1534 if (!conn->hchan) {
1535 ret = -ENODEV;
1536 goto out_unlock;
1537 }
1538
1539 ret = user->probe(conn, user);
1540 if (ret)
1541 goto out_unlock;
1542
1543 list_add(&user->list, &conn->users);
1544 ret = 0;
1545
1546out_unlock:
1547 hci_dev_unlock(hdev);
1548 return ret;
1549}
1550EXPORT_SYMBOL(l2cap_register_user);
1551
1552void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1553{
1554 struct hci_dev *hdev = conn->hcon->hdev;
1555
1556 hci_dev_lock(hdev);
1557
1558 if (!user->list.next || !user->list.prev)
1559 goto out_unlock;
1560
1561 list_del(&user->list);
1562 user->list.next = NULL;
1563 user->list.prev = NULL;
1564 user->remove(conn, user);
1565
1566out_unlock:
1567 hci_dev_unlock(hdev);
1568}
1569EXPORT_SYMBOL(l2cap_unregister_user);
1570
1571static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1572{
1573 struct l2cap_user *user;
1574
1575 while (!list_empty(&conn->users)) {
1576 user = list_first_entry(&conn->users, struct l2cap_user, list);
1577 list_del(&user->list);
1578 user->list.next = NULL;
1579 user->list.prev = NULL;
1580 user->remove(conn, user);
1581 }
1582}
1583
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001584static void l2cap_conn_del(struct hci_conn *hcon, int err)
1585{
1586 struct l2cap_conn *conn = hcon->l2cap_data;
1587 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001588
1589 if (!conn)
1590 return;
1591
1592 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1593
1594 kfree_skb(conn->rx_skb);
1595
David Herrmann2c8e1412013-04-06 20:28:45 +02001596 l2cap_unregister_all_users(conn);
1597
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001598 mutex_lock(&conn->chan_lock);
1599
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001600 /* Kill channels */
1601 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001602 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001603 l2cap_chan_lock(chan);
1604
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001605 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001606
1607 l2cap_chan_unlock(chan);
1608
Gustavo Padovan80b98022012-05-27 22:27:51 -03001609 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001610 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001611 }
1612
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001613 mutex_unlock(&conn->chan_lock);
1614
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001615 hci_chan_del(conn->hchan);
1616
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001617 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001618 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001619
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001620 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001621 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001622 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001623 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001624
1625 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001626 conn->hchan = NULL;
1627 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001628}
1629
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001630static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001631{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001632 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001633 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001634
Johan Hedbergd06cc412012-06-06 18:44:11 +08001635 BT_DBG("conn %p", conn);
1636
1637 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1638 smp_chan_destroy(conn);
1639 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1640 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001641}
1642
Claudio Takahasibaf43252013-04-11 13:55:50 -03001643static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644{
Marcel Holtmann01394182006-07-03 10:02:46 +02001645 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001646 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001647
Claudio Takahasibaf43252013-04-11 13:55:50 -03001648 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001649 return conn;
1650
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001651 hchan = hci_chan_create(hcon);
1652 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001653 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001655 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001656 if (!conn) {
1657 hci_chan_del(hchan);
1658 return NULL;
1659 }
1660
David Herrmann9c903e32013-04-06 20:28:44 +02001661 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662 hcon->l2cap_data = conn;
1663 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001664 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001665 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001667 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001668
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001669 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001670 case LE_LINK:
1671 if (hcon->hdev->le_mtu) {
1672 conn->mtu = hcon->hdev->le_mtu;
1673 break;
1674 }
1675 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001676 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001677 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001678 break;
1679 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001680
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001681 conn->feat_mask = 0;
1682
Marcel Holtmann848566b2013-10-01 22:59:22 -07001683 if (hcon->type == ACL_LINK)
1684 conn->hs_enabled = test_bit(HCI_HS_ENABLED,
1685 &hcon->hdev->dev_flags);
1686
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001688 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001689
1690 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001691 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001693 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001694 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001695 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001696 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001697
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001698 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001699
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 return conn;
1701}
1702
David Herrmann9c903e32013-04-06 20:28:44 +02001703static void l2cap_conn_free(struct kref *ref)
1704{
1705 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1706
1707 hci_conn_put(conn->hcon);
1708 kfree(conn);
1709}
1710
1711void l2cap_conn_get(struct l2cap_conn *conn)
1712{
1713 kref_get(&conn->ref);
1714}
1715EXPORT_SYMBOL(l2cap_conn_get);
1716
1717void l2cap_conn_put(struct l2cap_conn *conn)
1718{
1719 kref_put(&conn->ref, l2cap_conn_free);
1720}
1721EXPORT_SYMBOL(l2cap_conn_put);
1722
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724
Ido Yarivc2287682012-04-20 15:46:07 -03001725/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726 * Returns closest match.
1727 */
Ido Yarivc2287682012-04-20 15:46:07 -03001728static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1729 bdaddr_t *src,
1730 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001732 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001734 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001735
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001736 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001737 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 continue;
1739
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001740 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001741 int src_match, dst_match;
1742 int src_any, dst_any;
1743
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001745 src_match = !bacmp(&c->src, src);
1746 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001747 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001748 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001749 return c;
1750 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001751
1752 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001753 src_any = !bacmp(&c->src, BDADDR_ANY);
1754 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001755 if ((src_match && dst_any) || (src_any && dst_match) ||
1756 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001757 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758 }
1759 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001761 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001762
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001763 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764}
1765
Andre Guedes8e9f9892012-04-24 21:02:55 -03001766int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1767 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769 struct l2cap_conn *conn;
1770 struct hci_conn *hcon;
1771 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001772 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001773 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001775 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301776 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001778 hdev = hci_get_route(dst, &chan->src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001779 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780 return -EHOSTUNREACH;
1781
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001782 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001784 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001785
1786 /* PSM must be odd and lsb of upper byte must be 0 */
1787 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001788 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001789 err = -EINVAL;
1790 goto done;
1791 }
1792
1793 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1794 err = -EINVAL;
1795 goto done;
1796 }
1797
1798 switch (chan->mode) {
1799 case L2CAP_MODE_BASIC:
1800 break;
1801 case L2CAP_MODE_ERTM:
1802 case L2CAP_MODE_STREAMING:
1803 if (!disable_ertm)
1804 break;
1805 /* fall through */
1806 default:
1807 err = -ENOTSUPP;
1808 goto done;
1809 }
1810
Gustavo Padovan0797e012012-05-27 22:27:54 -03001811 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001812 case BT_CONNECT:
1813 case BT_CONNECT2:
1814 case BT_CONFIG:
1815 /* Already connecting */
1816 err = 0;
1817 goto done;
1818
1819 case BT_CONNECTED:
1820 /* Already connected */
1821 err = -EISCONN;
1822 goto done;
1823
1824 case BT_OPEN:
1825 case BT_BOUND:
1826 /* Can connect */
1827 break;
1828
1829 default:
1830 err = -EBADFD;
1831 goto done;
1832 }
1833
1834 /* Set destination address and psm */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001835 bacpy(&chan->dst, dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001836 chan->dst_type = dst_type;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001837
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001838 chan->psm = psm;
1839 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001841 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001842
Johan Hedbergf224ca52013-04-29 19:35:36 +03001843 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001844 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001845 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001846 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001847 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001848 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001849
Ville Tervo30e76272011-02-22 16:10:53 -03001850 if (IS_ERR(hcon)) {
1851 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001852 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001853 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854
Claudio Takahasibaf43252013-04-11 13:55:50 -03001855 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001856 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001857 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001858 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859 goto done;
1860 }
1861
Johan Hedberg141d5702013-04-29 19:35:37 +03001862 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1863 hci_conn_drop(hcon);
1864 err = -EBUSY;
1865 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001866 }
1867
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868 /* Update source addr of the socket */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001869 bacpy(&chan->src, &hcon->src);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001870 chan->src_type = bdaddr_type(hcon, hcon->src_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001872 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001873 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001874 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001875
Johan Hedberg5ee98912013-04-29 19:35:43 +03001876 /* l2cap_chan_add takes its own ref so we can drop this one */
1877 hci_conn_drop(hcon);
1878
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001879 l2cap_state_change(chan, BT_CONNECT);
Gustavo Padovan8d836d72013-10-15 19:24:47 -03001880 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001881
1882 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001883 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001884 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001885 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001886 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001887 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001888 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889 }
1890
Ville Tervo30e76272011-02-22 16:10:53 -03001891 err = 0;
1892
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001894 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001895 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896 hci_dev_put(hdev);
1897 return err;
1898}
1899
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001900static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001901{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001902 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001903 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001904
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001905 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001906
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001907 l2cap_chan_lock(chan);
1908
Mat Martineau80909e02012-05-17 20:53:50 -07001909 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001910 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001911 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001912 return;
1913 }
1914
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001915 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001916
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001917 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001918 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001919}
1920
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001921static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001922{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001923 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001924 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001925
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001926 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001927
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001928 l2cap_chan_lock(chan);
1929
Mat Martineau80909e02012-05-17 20:53:50 -07001930 if (!chan->conn) {
1931 l2cap_chan_unlock(chan);
1932 l2cap_chan_put(chan);
1933 return;
1934 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001935
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001936 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001937 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001938 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001939}
1940
Gustavo Padovand6603662012-05-21 13:58:22 -03001941static void l2cap_streaming_send(struct l2cap_chan *chan,
1942 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001943{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001944 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001945 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001946
Mat Martineau37339372012-05-17 20:53:33 -07001947 BT_DBG("chan %p, skbs %p", chan, skbs);
1948
Mat Martineaub99e13a2012-10-23 15:24:19 -07001949 if (__chan_is_moving(chan))
1950 return;
1951
Mat Martineau37339372012-05-17 20:53:33 -07001952 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1953
1954 while (!skb_queue_empty(&chan->tx_q)) {
1955
1956 skb = skb_dequeue(&chan->tx_q);
1957
1958 bt_cb(skb)->control.retries = 1;
1959 control = &bt_cb(skb)->control;
1960
1961 control->reqseq = 0;
1962 control->txseq = chan->next_tx_seq;
1963
1964 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001965
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001966 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001967 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1968 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001969 }
1970
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001971 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001972
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001973 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001974
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001975 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001976 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001977 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001978}
1979
Szymon Janc67c9e842011-07-28 16:24:33 +02001980static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001981{
1982 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001983 struct l2cap_ctrl *control;
1984 int sent = 0;
1985
1986 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001987
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001988 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001989 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001990
Mat Martineau94122bb2012-05-02 09:42:02 -07001991 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1992 return 0;
1993
Mat Martineaub99e13a2012-10-23 15:24:19 -07001994 if (__chan_is_moving(chan))
1995 return 0;
1996
Mat Martineau18a48e72012-05-17 20:53:34 -07001997 while (chan->tx_send_head &&
1998 chan->unacked_frames < chan->remote_tx_win &&
1999 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002000
Mat Martineau18a48e72012-05-17 20:53:34 -07002001 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002002
Mat Martineau18a48e72012-05-17 20:53:34 -07002003 bt_cb(skb)->control.retries = 1;
2004 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03002005
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002006 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07002007 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002008
Mat Martineau18a48e72012-05-17 20:53:34 -07002009 control->reqseq = chan->buffer_seq;
2010 chan->last_acked_seq = chan->buffer_seq;
2011 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002012
Mat Martineau18a48e72012-05-17 20:53:34 -07002013 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002014
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002015 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07002016 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2017 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002018 }
2019
Mat Martineau18a48e72012-05-17 20:53:34 -07002020 /* Clone after data has been modified. Data is assumed to be
2021 read-only (for locking purposes) on cloned sk_buffs.
2022 */
2023 tx_skb = skb_clone(skb, GFP_KERNEL);
2024
2025 if (!tx_skb)
2026 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002027
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002028 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002029
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002030 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002031 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002032 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002033 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002034
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002035 if (skb_queue_is_last(&chan->tx_q, skb))
2036 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002037 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002038 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002039
2040 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002041 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002042 }
2043
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002044 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2045 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002046
2047 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002048}
2049
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002050static void l2cap_ertm_resend(struct l2cap_chan *chan)
2051{
2052 struct l2cap_ctrl control;
2053 struct sk_buff *skb;
2054 struct sk_buff *tx_skb;
2055 u16 seq;
2056
2057 BT_DBG("chan %p", chan);
2058
2059 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2060 return;
2061
Mat Martineaub99e13a2012-10-23 15:24:19 -07002062 if (__chan_is_moving(chan))
2063 return;
2064
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002065 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2066 seq = l2cap_seq_list_pop(&chan->retrans_list);
2067
2068 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2069 if (!skb) {
2070 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002071 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002072 continue;
2073 }
2074
2075 bt_cb(skb)->control.retries++;
2076 control = bt_cb(skb)->control;
2077
2078 if (chan->max_tx != 0 &&
2079 bt_cb(skb)->control.retries > chan->max_tx) {
2080 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002081 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002082 l2cap_seq_list_clear(&chan->retrans_list);
2083 break;
2084 }
2085
2086 control.reqseq = chan->buffer_seq;
2087 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2088 control.final = 1;
2089 else
2090 control.final = 0;
2091
2092 if (skb_cloned(skb)) {
2093 /* Cloned sk_buffs are read-only, so we need a
2094 * writeable copy
2095 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002096 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002097 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002098 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002099 }
2100
2101 if (!tx_skb) {
2102 l2cap_seq_list_clear(&chan->retrans_list);
2103 break;
2104 }
2105
2106 /* Update skb contents */
2107 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2108 put_unaligned_le32(__pack_extended_control(&control),
2109 tx_skb->data + L2CAP_HDR_SIZE);
2110 } else {
2111 put_unaligned_le16(__pack_enhanced_control(&control),
2112 tx_skb->data + L2CAP_HDR_SIZE);
2113 }
2114
2115 if (chan->fcs == L2CAP_FCS_CRC16) {
2116 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2117 put_unaligned_le16(fcs, skb_put(tx_skb,
2118 L2CAP_FCS_SIZE));
2119 }
2120
2121 l2cap_do_send(chan, tx_skb);
2122
2123 BT_DBG("Resent txseq %d", control.txseq);
2124
2125 chan->last_acked_seq = chan->buffer_seq;
2126 }
2127}
2128
Mat Martineauf80842a2012-05-17 20:53:46 -07002129static void l2cap_retransmit(struct l2cap_chan *chan,
2130 struct l2cap_ctrl *control)
2131{
2132 BT_DBG("chan %p, control %p", chan, control);
2133
2134 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2135 l2cap_ertm_resend(chan);
2136}
2137
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002138static void l2cap_retransmit_all(struct l2cap_chan *chan,
2139 struct l2cap_ctrl *control)
2140{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002141 struct sk_buff *skb;
2142
2143 BT_DBG("chan %p, control %p", chan, control);
2144
2145 if (control->poll)
2146 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2147
2148 l2cap_seq_list_clear(&chan->retrans_list);
2149
2150 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2151 return;
2152
2153 if (chan->unacked_frames) {
2154 skb_queue_walk(&chan->tx_q, skb) {
2155 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002156 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002157 break;
2158 }
2159
2160 skb_queue_walk_from(&chan->tx_q, skb) {
2161 if (skb == chan->tx_send_head)
2162 break;
2163
2164 l2cap_seq_list_append(&chan->retrans_list,
2165 bt_cb(skb)->control.txseq);
2166 }
2167
2168 l2cap_ertm_resend(chan);
2169 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002170}
2171
Szymon Jancb17e73b2012-01-11 10:59:47 +01002172static void l2cap_send_ack(struct l2cap_chan *chan)
2173{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002174 struct l2cap_ctrl control;
2175 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2176 chan->last_acked_seq);
2177 int threshold;
2178
2179 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2180 chan, chan->last_acked_seq, chan->buffer_seq);
2181
2182 memset(&control, 0, sizeof(control));
2183 control.sframe = 1;
2184
2185 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2186 chan->rx_state == L2CAP_RX_STATE_RECV) {
2187 __clear_ack_timer(chan);
2188 control.super = L2CAP_SUPER_RNR;
2189 control.reqseq = chan->buffer_seq;
2190 l2cap_send_sframe(chan, &control);
2191 } else {
2192 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2193 l2cap_ertm_send(chan);
2194 /* If any i-frames were sent, they included an ack */
2195 if (chan->buffer_seq == chan->last_acked_seq)
2196 frames_to_ack = 0;
2197 }
2198
Mat Martineauc20f8e32012-07-10 05:47:07 -07002199 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002200 * Calculate without mul or div
2201 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002202 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002203 threshold += threshold << 1;
2204 threshold >>= 2;
2205
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002206 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002207 threshold);
2208
2209 if (frames_to_ack >= threshold) {
2210 __clear_ack_timer(chan);
2211 control.super = L2CAP_SUPER_RR;
2212 control.reqseq = chan->buffer_seq;
2213 l2cap_send_sframe(chan, &control);
2214 frames_to_ack = 0;
2215 }
2216
2217 if (frames_to_ack)
2218 __set_ack_timer(chan);
2219 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002220}
2221
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002222static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2223 struct msghdr *msg, int len,
2224 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002225{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002226 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002227 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002228 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002229
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002230 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002231 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002232
2233 sent += count;
2234 len -= count;
2235
2236 /* Continuation fragments (no L2CAP header) */
2237 frag = &skb_shinfo(skb)->frag_list;
2238 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002239 struct sk_buff *tmp;
2240
Linus Torvalds1da177e2005-04-16 15:20:36 -07002241 count = min_t(unsigned int, conn->mtu, len);
2242
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002243 tmp = chan->ops->alloc_skb(chan, count,
2244 msg->msg_flags & MSG_DONTWAIT);
2245 if (IS_ERR(tmp))
2246 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002247
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002248 *frag = tmp;
2249
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002250 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2251 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002253 (*frag)->priority = skb->priority;
2254
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255 sent += count;
2256 len -= count;
2257
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002258 skb->len += (*frag)->len;
2259 skb->data_len += (*frag)->len;
2260
Linus Torvalds1da177e2005-04-16 15:20:36 -07002261 frag = &(*frag)->next;
2262 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002263
2264 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002265}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002266
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002267static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002268 struct msghdr *msg, size_t len,
2269 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002270{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002271 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002272 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002273 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002274 struct l2cap_hdr *lh;
2275
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002276 BT_DBG("chan %p psm 0x%2.2x len %zu priority %u", chan,
2277 __le16_to_cpu(chan->psm), len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002278
2279 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002280
2281 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002282 msg->msg_flags & MSG_DONTWAIT);
2283 if (IS_ERR(skb))
2284 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002285
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002286 skb->priority = priority;
2287
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002288 /* Create L2CAP header */
2289 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002290 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002291 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002292 put_unaligned(chan->psm, (__le16 *) skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002293
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002294 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002295 if (unlikely(err < 0)) {
2296 kfree_skb(skb);
2297 return ERR_PTR(err);
2298 }
2299 return skb;
2300}
2301
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002302static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002303 struct msghdr *msg, size_t len,
2304 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002305{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002306 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002307 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002308 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002309 struct l2cap_hdr *lh;
2310
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002311 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002312
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002313 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002314
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002315 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002316 msg->msg_flags & MSG_DONTWAIT);
2317 if (IS_ERR(skb))
2318 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002319
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002320 skb->priority = priority;
2321
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002322 /* Create L2CAP header */
2323 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002324 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002325 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002326
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002327 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002328 if (unlikely(err < 0)) {
2329 kfree_skb(skb);
2330 return ERR_PTR(err);
2331 }
2332 return skb;
2333}
2334
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002335static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002336 struct msghdr *msg, size_t len,
2337 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002338{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002339 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002340 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002341 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002342 struct l2cap_hdr *lh;
2343
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002344 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002345
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002346 if (!conn)
2347 return ERR_PTR(-ENOTCONN);
2348
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002349 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002350
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002351 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002352 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002353
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002354 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002355 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002356
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002357 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002358
2359 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002360 msg->msg_flags & MSG_DONTWAIT);
2361 if (IS_ERR(skb))
2362 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002363
2364 /* Create L2CAP header */
2365 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002366 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002367 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002368
Mat Martineau18a48e72012-05-17 20:53:34 -07002369 /* Control header is populated later */
2370 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2371 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2372 else
2373 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002374
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002375 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002376 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002377
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002378 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002379 if (unlikely(err < 0)) {
2380 kfree_skb(skb);
2381 return ERR_PTR(err);
2382 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002383
Mat Martineau18a48e72012-05-17 20:53:34 -07002384 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002385 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002386 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002387}
2388
Mat Martineau94122bb2012-05-02 09:42:02 -07002389static int l2cap_segment_sdu(struct l2cap_chan *chan,
2390 struct sk_buff_head *seg_queue,
2391 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002392{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002393 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002394 u16 sdu_len;
2395 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002396 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002397
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002398 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002399
Mat Martineau94122bb2012-05-02 09:42:02 -07002400 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2401 * so fragmented skbs are not used. The HCI layer's handling
2402 * of fragmented skbs is not compatible with ERTM's queueing.
2403 */
2404
2405 /* PDU size is derived from the HCI MTU */
2406 pdu_len = chan->conn->mtu;
2407
Mat Martineaua5495742012-10-23 15:24:21 -07002408 /* Constrain PDU size for BR/EDR connections */
2409 if (!chan->hs_hcon)
2410 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002411
2412 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002413 if (chan->fcs)
2414 pdu_len -= L2CAP_FCS_SIZE;
2415
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002416 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002417
2418 /* Remote device may have requested smaller PDUs */
2419 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2420
2421 if (len <= pdu_len) {
2422 sar = L2CAP_SAR_UNSEGMENTED;
2423 sdu_len = 0;
2424 pdu_len = len;
2425 } else {
2426 sar = L2CAP_SAR_START;
2427 sdu_len = len;
2428 pdu_len -= L2CAP_SDULEN_SIZE;
2429 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002430
2431 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002432 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002433
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002434 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002435 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002436 return PTR_ERR(skb);
2437 }
2438
Mat Martineau94122bb2012-05-02 09:42:02 -07002439 bt_cb(skb)->control.sar = sar;
2440 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002441
Mat Martineau94122bb2012-05-02 09:42:02 -07002442 len -= pdu_len;
2443 if (sdu_len) {
2444 sdu_len = 0;
2445 pdu_len += L2CAP_SDULEN_SIZE;
2446 }
2447
2448 if (len <= pdu_len) {
2449 sar = L2CAP_SAR_END;
2450 pdu_len = len;
2451 } else {
2452 sar = L2CAP_SAR_CONTINUE;
2453 }
2454 }
2455
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002456 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002457}
2458
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002459int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002460 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002461{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002462 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002463 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002464 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002465
2466 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002467 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002468 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002469 if (IS_ERR(skb))
2470 return PTR_ERR(skb);
2471
2472 l2cap_do_send(chan, skb);
2473 return len;
2474 }
2475
2476 switch (chan->mode) {
2477 case L2CAP_MODE_BASIC:
2478 /* Check outgoing MTU */
2479 if (len > chan->omtu)
2480 return -EMSGSIZE;
2481
2482 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002483 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002484 if (IS_ERR(skb))
2485 return PTR_ERR(skb);
2486
2487 l2cap_do_send(chan, skb);
2488 err = len;
2489 break;
2490
2491 case L2CAP_MODE_ERTM:
2492 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002493 /* Check outgoing MTU */
2494 if (len > chan->omtu) {
2495 err = -EMSGSIZE;
2496 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002497 }
2498
Mat Martineau94122bb2012-05-02 09:42:02 -07002499 __skb_queue_head_init(&seg_queue);
2500
2501 /* Do segmentation before calling in to the state machine,
2502 * since it's possible to block while waiting for memory
2503 * allocation.
2504 */
2505 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2506
2507 /* The channel could have been closed while segmenting,
2508 * check that it is still connected.
2509 */
2510 if (chan->state != BT_CONNECTED) {
2511 __skb_queue_purge(&seg_queue);
2512 err = -ENOTCONN;
2513 }
2514
2515 if (err)
2516 break;
2517
Mat Martineau37339372012-05-17 20:53:33 -07002518 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002519 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002520 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002521 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002522
Gustavo Padovand6603662012-05-21 13:58:22 -03002523 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002524
Mat Martineau94122bb2012-05-02 09:42:02 -07002525 /* If the skbs were not queued for sending, they'll still be in
2526 * seg_queue and need to be purged.
2527 */
2528 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002529 break;
2530
2531 default:
2532 BT_DBG("bad state %1.1x", chan->mode);
2533 err = -EBADFD;
2534 }
2535
2536 return err;
2537}
2538
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002539static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2540{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002541 struct l2cap_ctrl control;
2542 u16 seq;
2543
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002544 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002545
2546 memset(&control, 0, sizeof(control));
2547 control.sframe = 1;
2548 control.super = L2CAP_SUPER_SREJ;
2549
2550 for (seq = chan->expected_tx_seq; seq != txseq;
2551 seq = __next_seq(chan, seq)) {
2552 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2553 control.reqseq = seq;
2554 l2cap_send_sframe(chan, &control);
2555 l2cap_seq_list_append(&chan->srej_list, seq);
2556 }
2557 }
2558
2559 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002560}
2561
2562static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2563{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002564 struct l2cap_ctrl control;
2565
2566 BT_DBG("chan %p", chan);
2567
2568 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2569 return;
2570
2571 memset(&control, 0, sizeof(control));
2572 control.sframe = 1;
2573 control.super = L2CAP_SUPER_SREJ;
2574 control.reqseq = chan->srej_list.tail;
2575 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002576}
2577
2578static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2579{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002580 struct l2cap_ctrl control;
2581 u16 initial_head;
2582 u16 seq;
2583
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002584 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002585
2586 memset(&control, 0, sizeof(control));
2587 control.sframe = 1;
2588 control.super = L2CAP_SUPER_SREJ;
2589
2590 /* Capture initial list head to allow only one pass through the list. */
2591 initial_head = chan->srej_list.head;
2592
2593 do {
2594 seq = l2cap_seq_list_pop(&chan->srej_list);
2595 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2596 break;
2597
2598 control.reqseq = seq;
2599 l2cap_send_sframe(chan, &control);
2600 l2cap_seq_list_append(&chan->srej_list, seq);
2601 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002602}
2603
Mat Martineau608bcc62012-05-17 20:53:32 -07002604static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2605{
2606 struct sk_buff *acked_skb;
2607 u16 ackseq;
2608
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002609 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002610
2611 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2612 return;
2613
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002614 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002615 chan->expected_ack_seq, chan->unacked_frames);
2616
2617 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2618 ackseq = __next_seq(chan, ackseq)) {
2619
2620 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2621 if (acked_skb) {
2622 skb_unlink(acked_skb, &chan->tx_q);
2623 kfree_skb(acked_skb);
2624 chan->unacked_frames--;
2625 }
2626 }
2627
2628 chan->expected_ack_seq = reqseq;
2629
2630 if (chan->unacked_frames == 0)
2631 __clear_retrans_timer(chan);
2632
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002633 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002634}
2635
2636static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2637{
2638 BT_DBG("chan %p", chan);
2639
2640 chan->expected_tx_seq = chan->buffer_seq;
2641 l2cap_seq_list_clear(&chan->srej_list);
2642 skb_queue_purge(&chan->srej_q);
2643 chan->rx_state = L2CAP_RX_STATE_RECV;
2644}
2645
Gustavo Padovand6603662012-05-21 13:58:22 -03002646static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2647 struct l2cap_ctrl *control,
2648 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002649{
Mat Martineau608bcc62012-05-17 20:53:32 -07002650 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2651 event);
2652
2653 switch (event) {
2654 case L2CAP_EV_DATA_REQUEST:
2655 if (chan->tx_send_head == NULL)
2656 chan->tx_send_head = skb_peek(skbs);
2657
2658 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2659 l2cap_ertm_send(chan);
2660 break;
2661 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2662 BT_DBG("Enter LOCAL_BUSY");
2663 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2664
2665 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2666 /* The SREJ_SENT state must be aborted if we are to
2667 * enter the LOCAL_BUSY state.
2668 */
2669 l2cap_abort_rx_srej_sent(chan);
2670 }
2671
2672 l2cap_send_ack(chan);
2673
2674 break;
2675 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2676 BT_DBG("Exit LOCAL_BUSY");
2677 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2678
2679 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2680 struct l2cap_ctrl local_control;
2681
2682 memset(&local_control, 0, sizeof(local_control));
2683 local_control.sframe = 1;
2684 local_control.super = L2CAP_SUPER_RR;
2685 local_control.poll = 1;
2686 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002687 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002688
2689 chan->retry_count = 1;
2690 __set_monitor_timer(chan);
2691 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2692 }
2693 break;
2694 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2695 l2cap_process_reqseq(chan, control->reqseq);
2696 break;
2697 case L2CAP_EV_EXPLICIT_POLL:
2698 l2cap_send_rr_or_rnr(chan, 1);
2699 chan->retry_count = 1;
2700 __set_monitor_timer(chan);
2701 __clear_ack_timer(chan);
2702 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2703 break;
2704 case L2CAP_EV_RETRANS_TO:
2705 l2cap_send_rr_or_rnr(chan, 1);
2706 chan->retry_count = 1;
2707 __set_monitor_timer(chan);
2708 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2709 break;
2710 case L2CAP_EV_RECV_FBIT:
2711 /* Nothing to process */
2712 break;
2713 default:
2714 break;
2715 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002716}
2717
Gustavo Padovand6603662012-05-21 13:58:22 -03002718static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2719 struct l2cap_ctrl *control,
2720 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002721{
Mat Martineau608bcc62012-05-17 20:53:32 -07002722 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2723 event);
2724
2725 switch (event) {
2726 case L2CAP_EV_DATA_REQUEST:
2727 if (chan->tx_send_head == NULL)
2728 chan->tx_send_head = skb_peek(skbs);
2729 /* Queue data, but don't send. */
2730 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2731 break;
2732 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2733 BT_DBG("Enter LOCAL_BUSY");
2734 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2735
2736 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2737 /* The SREJ_SENT state must be aborted if we are to
2738 * enter the LOCAL_BUSY state.
2739 */
2740 l2cap_abort_rx_srej_sent(chan);
2741 }
2742
2743 l2cap_send_ack(chan);
2744
2745 break;
2746 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2747 BT_DBG("Exit LOCAL_BUSY");
2748 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2749
2750 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2751 struct l2cap_ctrl local_control;
2752 memset(&local_control, 0, sizeof(local_control));
2753 local_control.sframe = 1;
2754 local_control.super = L2CAP_SUPER_RR;
2755 local_control.poll = 1;
2756 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002757 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002758
2759 chan->retry_count = 1;
2760 __set_monitor_timer(chan);
2761 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2762 }
2763 break;
2764 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2765 l2cap_process_reqseq(chan, control->reqseq);
2766
2767 /* Fall through */
2768
2769 case L2CAP_EV_RECV_FBIT:
2770 if (control && control->final) {
2771 __clear_monitor_timer(chan);
2772 if (chan->unacked_frames > 0)
2773 __set_retrans_timer(chan);
2774 chan->retry_count = 0;
2775 chan->tx_state = L2CAP_TX_STATE_XMIT;
2776 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2777 }
2778 break;
2779 case L2CAP_EV_EXPLICIT_POLL:
2780 /* Ignore */
2781 break;
2782 case L2CAP_EV_MONITOR_TO:
2783 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2784 l2cap_send_rr_or_rnr(chan, 1);
2785 __set_monitor_timer(chan);
2786 chan->retry_count++;
2787 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002788 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002789 }
2790 break;
2791 default:
2792 break;
2793 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002794}
2795
Gustavo Padovand6603662012-05-21 13:58:22 -03002796static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2797 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002798{
Mat Martineau608bcc62012-05-17 20:53:32 -07002799 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2800 chan, control, skbs, event, chan->tx_state);
2801
2802 switch (chan->tx_state) {
2803 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002804 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002805 break;
2806 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002807 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002808 break;
2809 default:
2810 /* Ignore event */
2811 break;
2812 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002813}
2814
Mat Martineau4b51dae92012-05-17 20:53:37 -07002815static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2816 struct l2cap_ctrl *control)
2817{
2818 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002819 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002820}
2821
Mat Martineauf80842a2012-05-17 20:53:46 -07002822static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2823 struct l2cap_ctrl *control)
2824{
2825 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002826 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002827}
2828
Linus Torvalds1da177e2005-04-16 15:20:36 -07002829/* Copy frame to all raw sockets on that connection */
2830static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2831{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002832 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002833 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002834
2835 BT_DBG("conn %p", conn);
2836
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002837 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002838
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002839 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002840 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002841 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002842 continue;
2843
2844 /* Don't send frame to the socket it came from */
2845 if (skb->sk == sk)
2846 continue;
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002847 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002848 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002849 continue;
2850
Gustavo Padovan80b98022012-05-27 22:27:51 -03002851 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002852 kfree_skb(nskb);
2853 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002854
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002855 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002856}
2857
2858/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002859static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2860 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002861{
2862 struct sk_buff *skb, **frag;
2863 struct l2cap_cmd_hdr *cmd;
2864 struct l2cap_hdr *lh;
2865 int len, count;
2866
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002867 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2868 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002869
Anderson Lizardo300b9622013-06-02 16:30:40 -04002870 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2871 return NULL;
2872
Linus Torvalds1da177e2005-04-16 15:20:36 -07002873 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2874 count = min_t(unsigned int, conn->mtu, len);
2875
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002876 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002877 if (!skb)
2878 return NULL;
2879
2880 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002881 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002882
2883 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002884 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002885 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002886 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002887
2888 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2889 cmd->code = code;
2890 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002891 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002892
2893 if (dlen) {
2894 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2895 memcpy(skb_put(skb, count), data, count);
2896 data += count;
2897 }
2898
2899 len -= skb->len;
2900
2901 /* Continuation fragments (no L2CAP header) */
2902 frag = &skb_shinfo(skb)->frag_list;
2903 while (len) {
2904 count = min_t(unsigned int, conn->mtu, len);
2905
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002906 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002907 if (!*frag)
2908 goto fail;
2909
2910 memcpy(skb_put(*frag, count), data, count);
2911
2912 len -= count;
2913 data += count;
2914
2915 frag = &(*frag)->next;
2916 }
2917
2918 return skb;
2919
2920fail:
2921 kfree_skb(skb);
2922 return NULL;
2923}
2924
Gustavo Padovan2d792812012-10-06 10:07:01 +01002925static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2926 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927{
2928 struct l2cap_conf_opt *opt = *ptr;
2929 int len;
2930
2931 len = L2CAP_CONF_OPT_SIZE + opt->len;
2932 *ptr += len;
2933
2934 *type = opt->type;
2935 *olen = opt->len;
2936
2937 switch (opt->len) {
2938 case 1:
2939 *val = *((u8 *) opt->val);
2940 break;
2941
2942 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002943 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002944 break;
2945
2946 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002947 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002948 break;
2949
2950 default:
2951 *val = (unsigned long) opt->val;
2952 break;
2953 }
2954
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002955 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002956 return len;
2957}
2958
Linus Torvalds1da177e2005-04-16 15:20:36 -07002959static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2960{
2961 struct l2cap_conf_opt *opt = *ptr;
2962
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002963 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002964
2965 opt->type = type;
2966 opt->len = len;
2967
2968 switch (len) {
2969 case 1:
2970 *((u8 *) opt->val) = val;
2971 break;
2972
2973 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002974 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002975 break;
2976
2977 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002978 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979 break;
2980
2981 default:
2982 memcpy(opt->val, (void *) val, len);
2983 break;
2984 }
2985
2986 *ptr += L2CAP_CONF_OPT_SIZE + len;
2987}
2988
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002989static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2990{
2991 struct l2cap_conf_efs efs;
2992
Szymon Janc1ec918c2011-11-16 09:32:21 +01002993 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002994 case L2CAP_MODE_ERTM:
2995 efs.id = chan->local_id;
2996 efs.stype = chan->local_stype;
2997 efs.msdu = cpu_to_le16(chan->local_msdu);
2998 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002999 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003000 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003001 break;
3002
3003 case L2CAP_MODE_STREAMING:
3004 efs.id = 1;
3005 efs.stype = L2CAP_SERV_BESTEFFORT;
3006 efs.msdu = cpu_to_le16(chan->local_msdu);
3007 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
3008 efs.acc_lat = 0;
3009 efs.flush_to = 0;
3010 break;
3011
3012 default:
3013 return;
3014 }
3015
3016 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003017 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003018}
3019
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003020static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003021{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003022 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003023 ack_timer.work);
3024 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003025
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003026 BT_DBG("chan %p", chan);
3027
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003028 l2cap_chan_lock(chan);
3029
Mat Martineau03625202012-05-17 20:53:51 -07003030 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3031 chan->last_acked_seq);
3032
3033 if (frames_to_ack)
3034 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003035
3036 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003037 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003038}
3039
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003040int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003041{
Mat Martineau3c588192012-04-11 10:48:42 -07003042 int err;
3043
Mat Martineau105bdf92012-04-27 16:50:48 -07003044 chan->next_tx_seq = 0;
3045 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003046 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003047 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003048 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003049 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003050 chan->last_acked_seq = 0;
3051 chan->sdu = NULL;
3052 chan->sdu_last_frag = NULL;
3053 chan->sdu_len = 0;
3054
Mat Martineaud34c34f2012-05-14 14:49:27 -07003055 skb_queue_head_init(&chan->tx_q);
3056
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003057 chan->local_amp_id = AMP_ID_BREDR;
3058 chan->move_id = AMP_ID_BREDR;
Mat Martineau08333282012-10-23 15:24:06 -07003059 chan->move_state = L2CAP_MOVE_STABLE;
3060 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3061
Mat Martineau105bdf92012-04-27 16:50:48 -07003062 if (chan->mode != L2CAP_MODE_ERTM)
3063 return 0;
3064
3065 chan->rx_state = L2CAP_RX_STATE_RECV;
3066 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003067
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003068 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3069 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3070 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003071
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003072 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003073
Mat Martineau3c588192012-04-11 10:48:42 -07003074 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3075 if (err < 0)
3076 return err;
3077
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003078 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3079 if (err < 0)
3080 l2cap_seq_list_free(&chan->srej_list);
3081
3082 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003083}
3084
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003085static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3086{
3087 switch (mode) {
3088 case L2CAP_MODE_STREAMING:
3089 case L2CAP_MODE_ERTM:
3090 if (l2cap_mode_supported(mode, remote_feat_mask))
3091 return mode;
3092 /* fall through */
3093 default:
3094 return L2CAP_MODE_BASIC;
3095 }
3096}
3097
Marcel Holtmann848566b2013-10-01 22:59:22 -07003098static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003099{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003100 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003101}
3102
Marcel Holtmann848566b2013-10-01 22:59:22 -07003103static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003104{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003105 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003106}
3107
Mat Martineau36c86c82012-10-23 15:24:20 -07003108static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3109 struct l2cap_conf_rfc *rfc)
3110{
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003111 if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) {
Mat Martineau36c86c82012-10-23 15:24:20 -07003112 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3113
3114 /* Class 1 devices have must have ERTM timeouts
3115 * exceeding the Link Supervision Timeout. The
3116 * default Link Supervision Timeout for AMP
3117 * controllers is 10 seconds.
3118 *
3119 * Class 1 devices use 0xffffffff for their
3120 * best-effort flush timeout, so the clamping logic
3121 * will result in a timeout that meets the above
3122 * requirement. ERTM timeouts are 16-bit values, so
3123 * the maximum timeout is 65.535 seconds.
3124 */
3125
3126 /* Convert timeout to milliseconds and round */
3127 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3128
3129 /* This is the recommended formula for class 2 devices
3130 * that start ERTM timers when packets are sent to the
3131 * controller.
3132 */
3133 ertm_to = 3 * ertm_to + 500;
3134
3135 if (ertm_to > 0xffff)
3136 ertm_to = 0xffff;
3137
3138 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3139 rfc->monitor_timeout = rfc->retrans_timeout;
3140 } else {
3141 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3142 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3143 }
3144}
3145
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003146static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3147{
3148 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Marcel Holtmann848566b2013-10-01 22:59:22 -07003149 __l2cap_ews_supported(chan->conn)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003150 /* use extended control field */
3151 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003152 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3153 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003154 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003155 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003156 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3157 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003158 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003159}
3160
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003161static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003162{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003163 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003164 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003165 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003166 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003167
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003168 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003169
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003170 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003171 goto done;
3172
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003173 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003174 case L2CAP_MODE_STREAMING:
3175 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003176 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003177 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003178
Marcel Holtmann848566b2013-10-01 22:59:22 -07003179 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003180 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3181
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003182 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003183 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003184 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003185 break;
3186 }
3187
3188done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003189 if (chan->imtu != L2CAP_DEFAULT_MTU)
3190 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003191
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003192 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003193 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003194 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003195 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003196 break;
3197
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003198 rfc.mode = L2CAP_MODE_BASIC;
3199 rfc.txwin_size = 0;
3200 rfc.max_transmit = 0;
3201 rfc.retrans_timeout = 0;
3202 rfc.monitor_timeout = 0;
3203 rfc.max_pdu_size = 0;
3204
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003205 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003206 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003207 break;
3208
3209 case L2CAP_MODE_ERTM:
3210 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003211 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003212
3213 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003214
3215 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003216 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3217 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003218 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003219
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003220 l2cap_txwin_setup(chan);
3221
3222 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003223 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003224
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003225 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003226 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003227
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003228 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3229 l2cap_add_opt_efs(&ptr, chan);
3230
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003231 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3232 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003233 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003234
3235 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3236 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003237 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003238 chan->fcs = L2CAP_FCS_NONE;
3239 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3240 chan->fcs);
3241 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003242 break;
3243
3244 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003245 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003246 rfc.mode = L2CAP_MODE_STREAMING;
3247 rfc.txwin_size = 0;
3248 rfc.max_transmit = 0;
3249 rfc.retrans_timeout = 0;
3250 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003251
3252 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003253 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3254 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003255 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003256
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003257 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003258 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003259
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003260 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3261 l2cap_add_opt_efs(&ptr, chan);
3262
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003263 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3264 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003265 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003266 chan->fcs = L2CAP_FCS_NONE;
3267 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3268 chan->fcs);
3269 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003270 break;
3271 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003272
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003273 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003274 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003275
3276 return ptr - data;
3277}
3278
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003279static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003280{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003281 struct l2cap_conf_rsp *rsp = data;
3282 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003283 void *req = chan->conf_req;
3284 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003285 int type, hint, olen;
3286 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003287 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003288 struct l2cap_conf_efs efs;
3289 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003290 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003291 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003292 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003293
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003294 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003295
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003296 while (len >= L2CAP_CONF_OPT_SIZE) {
3297 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003298
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003299 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003300 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003301
3302 switch (type) {
3303 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003304 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003305 break;
3306
3307 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003308 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003309 break;
3310
3311 case L2CAP_CONF_QOS:
3312 break;
3313
Marcel Holtmann6464f352007-10-20 13:39:51 +02003314 case L2CAP_CONF_RFC:
3315 if (olen == sizeof(rfc))
3316 memcpy(&rfc, (void *) val, olen);
3317 break;
3318
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003319 case L2CAP_CONF_FCS:
3320 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003321 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003322 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003323
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003324 case L2CAP_CONF_EFS:
3325 remote_efs = 1;
3326 if (olen == sizeof(efs))
3327 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003328 break;
3329
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003330 case L2CAP_CONF_EWS:
Marcel Holtmann848566b2013-10-01 22:59:22 -07003331 if (!chan->conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003332 return -ECONNREFUSED;
3333
3334 set_bit(FLAG_EXT_CTRL, &chan->flags);
3335 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003336 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003337 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003338 break;
3339
3340 default:
3341 if (hint)
3342 break;
3343
3344 result = L2CAP_CONF_UNKNOWN;
3345 *((u8 *) ptr++) = type;
3346 break;
3347 }
3348 }
3349
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003350 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003351 goto done;
3352
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003353 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003354 case L2CAP_MODE_STREAMING:
3355 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003356 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003357 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003358 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003359 break;
3360 }
3361
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003362 if (remote_efs) {
Marcel Holtmann848566b2013-10-01 22:59:22 -07003363 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003364 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3365 else
3366 return -ECONNREFUSED;
3367 }
3368
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003369 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003370 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003371
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003372 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003373 }
3374
3375done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003376 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003377 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003378 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003379
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003380 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003381 return -ECONNREFUSED;
3382
Gustavo Padovan2d792812012-10-06 10:07:01 +01003383 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3384 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003385 }
3386
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003387 if (result == L2CAP_CONF_SUCCESS) {
3388 /* Configure output options and let the other side know
3389 * which ones we don't like. */
3390
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003391 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3392 result = L2CAP_CONF_UNACCEPT;
3393 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003394 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003395 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003396 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003397 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003398
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003399 if (remote_efs) {
3400 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003401 efs.stype != L2CAP_SERV_NOTRAFIC &&
3402 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003403
3404 result = L2CAP_CONF_UNACCEPT;
3405
3406 if (chan->num_conf_req >= 1)
3407 return -ECONNREFUSED;
3408
3409 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003410 sizeof(efs),
3411 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003412 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003413 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003414 result = L2CAP_CONF_PENDING;
3415 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003416 }
3417 }
3418
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003419 switch (rfc.mode) {
3420 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003421 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003422 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003423 break;
3424
3425 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003426 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3427 chan->remote_tx_win = rfc.txwin_size;
3428 else
3429 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3430
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003431 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003432
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003433 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003434 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3435 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003436 rfc.max_pdu_size = cpu_to_le16(size);
3437 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003438
Mat Martineau36c86c82012-10-23 15:24:20 -07003439 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003440
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003441 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003442
3443 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003444 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003445
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003446 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3447 chan->remote_id = efs.id;
3448 chan->remote_stype = efs.stype;
3449 chan->remote_msdu = le16_to_cpu(efs.msdu);
3450 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003451 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003452 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003453 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003454 chan->remote_sdu_itime =
3455 le32_to_cpu(efs.sdu_itime);
3456 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003457 sizeof(efs),
3458 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003459 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003460 break;
3461
3462 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003463 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003464 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3465 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003466 rfc.max_pdu_size = cpu_to_le16(size);
3467 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003468
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003469 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003470
Gustavo Padovan2d792812012-10-06 10:07:01 +01003471 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3472 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003473
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003474 break;
3475
3476 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003477 result = L2CAP_CONF_UNACCEPT;
3478
3479 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003480 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003481 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003482
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003483 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003484 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003485 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003486 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003487 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003488 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003489
3490 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003491}
3492
Gustavo Padovan2d792812012-10-06 10:07:01 +01003493static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3494 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003495{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003496 struct l2cap_conf_req *req = data;
3497 void *ptr = req->data;
3498 int type, olen;
3499 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003500 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003501 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003502
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003503 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003504
3505 while (len >= L2CAP_CONF_OPT_SIZE) {
3506 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3507
3508 switch (type) {
3509 case L2CAP_CONF_MTU:
3510 if (val < L2CAP_DEFAULT_MIN_MTU) {
3511 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003512 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003513 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003514 chan->imtu = val;
3515 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003516 break;
3517
3518 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003519 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003520 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003521 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003522 break;
3523
3524 case L2CAP_CONF_RFC:
3525 if (olen == sizeof(rfc))
3526 memcpy(&rfc, (void *)val, olen);
3527
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003528 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003529 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003530 return -ECONNREFUSED;
3531
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003532 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003533
3534 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003535 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003536 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003537
3538 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003539 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003540 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003541 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003542 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003543
3544 case L2CAP_CONF_EFS:
3545 if (olen == sizeof(efs))
3546 memcpy(&efs, (void *)val, olen);
3547
3548 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003549 efs.stype != L2CAP_SERV_NOTRAFIC &&
3550 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003551 return -ECONNREFUSED;
3552
Gustavo Padovan2d792812012-10-06 10:07:01 +01003553 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3554 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003555 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003556
3557 case L2CAP_CONF_FCS:
3558 if (*result == L2CAP_CONF_PENDING)
3559 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003560 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003561 &chan->conf_state);
3562 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003563 }
3564 }
3565
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003566 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003567 return -ECONNREFUSED;
3568
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003569 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003570
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003571 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003572 switch (rfc.mode) {
3573 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003574 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3575 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3576 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003577 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3578 chan->ack_win = min_t(u16, chan->ack_win,
3579 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003580
3581 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3582 chan->local_msdu = le16_to_cpu(efs.msdu);
3583 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003584 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003585 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3586 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003587 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003588 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003589 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003590
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003591 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003592 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003593 }
3594 }
3595
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003596 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003597 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003598
3599 return ptr - data;
3600}
3601
Gustavo Padovan2d792812012-10-06 10:07:01 +01003602static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3603 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003604{
3605 struct l2cap_conf_rsp *rsp = data;
3606 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003607
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003608 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003609
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003610 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003611 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003612 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003613
3614 return ptr - data;
3615}
3616
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003617void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003618{
3619 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003620 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003621 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003622 u8 rsp_code;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003623
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003624 rsp.scid = cpu_to_le16(chan->dcid);
3625 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003626 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3627 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003628
3629 if (chan->hs_hcon)
3630 rsp_code = L2CAP_CREATE_CHAN_RSP;
3631 else
3632 rsp_code = L2CAP_CONN_RSP;
3633
3634 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3635
3636 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003637
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003638 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003639 return;
3640
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003641 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003642 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003643 chan->num_conf_req++;
3644}
3645
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003646static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003647{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003648 int type, olen;
3649 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003650 /* Use sane default values in case a misbehaving remote device
3651 * did not send an RFC or extended window size option.
3652 */
3653 u16 txwin_ext = chan->ack_win;
3654 struct l2cap_conf_rfc rfc = {
3655 .mode = chan->mode,
3656 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3657 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3658 .max_pdu_size = cpu_to_le16(chan->imtu),
3659 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3660 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003661
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003662 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003663
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003664 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003665 return;
3666
3667 while (len >= L2CAP_CONF_OPT_SIZE) {
3668 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3669
Mat Martineauc20f8e32012-07-10 05:47:07 -07003670 switch (type) {
3671 case L2CAP_CONF_RFC:
3672 if (olen == sizeof(rfc))
3673 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003674 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003675 case L2CAP_CONF_EWS:
3676 txwin_ext = val;
3677 break;
3678 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003679 }
3680
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003681 switch (rfc.mode) {
3682 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003683 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3684 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003685 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3686 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3687 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3688 else
3689 chan->ack_win = min_t(u16, chan->ack_win,
3690 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003691 break;
3692 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003693 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003694 }
3695}
3696
Gustavo Padovan2d792812012-10-06 10:07:01 +01003697static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003698 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3699 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003700{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003701 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003702
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003703 if (cmd_len < sizeof(*rej))
3704 return -EPROTO;
3705
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003706 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003707 return 0;
3708
3709 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003710 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003711 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003712
3713 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003714 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003715
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003716 l2cap_conn_start(conn);
3717 }
3718
3719 return 0;
3720}
3721
Mat Martineau17009152012-10-23 15:24:07 -07003722static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3723 struct l2cap_cmd_hdr *cmd,
3724 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003725{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003726 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3727 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003728 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003729 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003730 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003731
3732 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003733 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003734
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003735 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003736
3737 /* Check if we have socket listening on psm */
Marcel Holtmann6f59b902013-10-13 05:24:01 -07003738 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07003739 &conn->hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003740 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003741 result = L2CAP_CR_BAD_PSM;
3742 goto sendresp;
3743 }
3744
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003745 parent = pchan->sk;
3746
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003747 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003748 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003749
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003750 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003751 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003752 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003753 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003754 result = L2CAP_CR_SEC_BLOCK;
3755 goto response;
3756 }
3757
Linus Torvalds1da177e2005-04-16 15:20:36 -07003758 result = L2CAP_CR_NO_MEM;
3759
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003760 /* Check if we already have channel with that dcid */
3761 if (__l2cap_get_chan_by_dcid(conn, scid))
3762 goto response;
3763
Gustavo Padovan80b98022012-05-27 22:27:51 -03003764 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003765 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003766 goto response;
3767
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003768 sk = chan->sk;
3769
Syam Sidhardhan330b6c12013-08-06 01:59:12 +09003770 /* For certain devices (ex: HID mouse), support for authentication,
3771 * pairing and bonding is optional. For such devices, inorder to avoid
3772 * the ACL alive for too long after L2CAP disconnection, reset the ACL
3773 * disc_timeout back to HCI_DISCONN_TIMEOUT during L2CAP connect.
3774 */
3775 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
3776
Marcel Holtmann7eafc592013-10-13 08:12:47 -07003777 bacpy(&chan->src, &conn->hcon->src);
3778 bacpy(&chan->dst, &conn->hcon->dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07003779 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
3780 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003781 chan->psm = psm;
3782 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003783 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003784
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003785 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003786
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003787 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003788
Gustavo Padovan8d836d72013-10-15 19:24:47 -03003789 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003790
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003791 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003792
Marcel Holtmann984947d2009-02-06 23:35:19 +01003793 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003794 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07003795 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003796 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003797 result = L2CAP_CR_PEND;
3798 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003799 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003800 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003801 /* Force pending result for AMP controllers.
3802 * The connection will succeed after the
3803 * physical link is up.
3804 */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003805 if (amp_id == AMP_ID_BREDR) {
Mat Martineau17009152012-10-23 15:24:07 -07003806 __l2cap_state_change(chan, BT_CONFIG);
3807 result = L2CAP_CR_SUCCESS;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003808 } else {
3809 __l2cap_state_change(chan, BT_CONNECT2);
3810 result = L2CAP_CR_PEND;
Mat Martineau17009152012-10-23 15:24:07 -07003811 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003812 status = L2CAP_CS_NO_INFO;
3813 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003814 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003815 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003816 result = L2CAP_CR_PEND;
3817 status = L2CAP_CS_AUTHEN_PEND;
3818 }
3819 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003820 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003821 result = L2CAP_CR_PEND;
3822 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003823 }
3824
Linus Torvalds1da177e2005-04-16 15:20:36 -07003825response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003826 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003827 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003828
3829sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003830 rsp.scid = cpu_to_le16(scid);
3831 rsp.dcid = cpu_to_le16(dcid);
3832 rsp.result = cpu_to_le16(result);
3833 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003834 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003835
3836 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3837 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003838 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003839
3840 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3841 conn->info_ident = l2cap_get_ident(conn);
3842
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003843 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003844
Gustavo Padovan2d792812012-10-06 10:07:01 +01003845 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3846 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003847 }
3848
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003849 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003850 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003851 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003852 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003853 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003854 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003855 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003856 }
Mat Martineau17009152012-10-23 15:24:07 -07003857
3858 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003859}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003860
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003861static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003862 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003863{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303864 struct hci_dev *hdev = conn->hcon->hdev;
3865 struct hci_conn *hcon = conn->hcon;
3866
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003867 if (cmd_len < sizeof(struct l2cap_conn_req))
3868 return -EPROTO;
3869
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303870 hci_dev_lock(hdev);
3871 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3872 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3873 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3874 hcon->dst_type, 0, NULL, 0,
3875 hcon->dev_class);
3876 hci_dev_unlock(hdev);
3877
Gustavo Padovan300229f2012-10-12 19:40:40 +08003878 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003879 return 0;
3880}
3881
Mat Martineau5909cf32012-10-23 15:24:08 -07003882static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003883 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3884 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003885{
3886 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3887 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003888 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003889 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003890 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003891
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003892 if (cmd_len < sizeof(*rsp))
3893 return -EPROTO;
3894
Linus Torvalds1da177e2005-04-16 15:20:36 -07003895 scid = __le16_to_cpu(rsp->scid);
3896 dcid = __le16_to_cpu(rsp->dcid);
3897 result = __le16_to_cpu(rsp->result);
3898 status = __le16_to_cpu(rsp->status);
3899
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003900 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 +01003901 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003902
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003903 mutex_lock(&conn->chan_lock);
3904
Linus Torvalds1da177e2005-04-16 15:20:36 -07003905 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003906 chan = __l2cap_get_chan_by_scid(conn, scid);
3907 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003908 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003909 goto unlock;
3910 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003911 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003912 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3913 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003914 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003915 goto unlock;
3916 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003917 }
3918
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003919 err = 0;
3920
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003921 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003922
Linus Torvalds1da177e2005-04-16 15:20:36 -07003923 switch (result) {
3924 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03003925 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003926 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003927 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003928 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003929
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003930 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003931 break;
3932
Linus Torvalds1da177e2005-04-16 15:20:36 -07003933 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003934 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003935 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003936 break;
3937
3938 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003939 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003940 break;
3941
3942 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003943 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003944 break;
3945 }
3946
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003947 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003948
3949unlock:
3950 mutex_unlock(&conn->chan_lock);
3951
3952 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003953}
3954
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003955static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003956{
3957 /* FCS is enabled only in ERTM or streaming mode, if one or both
3958 * sides request it.
3959 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003960 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003961 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003962 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003963 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003964}
3965
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003966static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3967 u8 ident, u16 flags)
3968{
3969 struct l2cap_conn *conn = chan->conn;
3970
3971 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3972 flags);
3973
3974 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3975 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3976
3977 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
3978 l2cap_build_conf_rsp(chan, data,
3979 L2CAP_CONF_SUCCESS, flags), data);
3980}
3981
Johan Hedberg662d6522013-10-16 11:20:47 +03003982static void cmd_reject_invalid_cid(struct l2cap_conn *conn, u8 ident,
3983 u16 scid, u16 dcid)
3984{
3985 struct l2cap_cmd_rej_cid rej;
3986
3987 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
3988 rej.scid = __cpu_to_le16(scid);
3989 rej.dcid = __cpu_to_le16(dcid);
3990
3991 l2cap_send_cmd(conn, ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3992}
3993
Gustavo Padovan2d792812012-10-06 10:07:01 +01003994static inline int l2cap_config_req(struct l2cap_conn *conn,
3995 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3996 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003997{
3998 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3999 u16 dcid, flags;
4000 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004001 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07004002 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004003
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004004 if (cmd_len < sizeof(*req))
4005 return -EPROTO;
4006
Linus Torvalds1da177e2005-04-16 15:20:36 -07004007 dcid = __le16_to_cpu(req->dcid);
4008 flags = __le16_to_cpu(req->flags);
4009
4010 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
4011
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004012 chan = l2cap_get_chan_by_scid(conn, dcid);
Johan Hedberg662d6522013-10-16 11:20:47 +03004013 if (!chan) {
4014 cmd_reject_invalid_cid(conn, cmd->ident, dcid, 0);
4015 return 0;
4016 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004017
David S. Miller033b1142011-07-21 13:38:42 -07004018 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Johan Hedberg662d6522013-10-16 11:20:47 +03004019 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4020 chan->dcid);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004021 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004022 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004023
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004024 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07004025 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004026 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004027 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004028 l2cap_build_conf_rsp(chan, rsp,
4029 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004030 goto unlock;
4031 }
4032
4033 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004034 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4035 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004036
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004037 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004038 /* Incomplete config. Send empty response. */
4039 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004040 l2cap_build_conf_rsp(chan, rsp,
4041 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004042 goto unlock;
4043 }
4044
4045 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004046 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004047 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004048 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004049 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004050 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004051
Mat Martineau1500109b2012-10-23 15:24:15 -07004052 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004053 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004054 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004055
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004056 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004057 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004058
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004059 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004060 goto unlock;
4061
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004062 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004063 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004064
Mat Martineau105bdf92012-04-27 16:50:48 -07004065 if (chan->mode == L2CAP_MODE_ERTM ||
4066 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004067 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004068
Mat Martineau3c588192012-04-11 10:48:42 -07004069 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004070 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004071 else
4072 l2cap_chan_ready(chan);
4073
Marcel Holtmann876d9482007-10-20 13:35:42 +02004074 goto unlock;
4075 }
4076
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004077 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004078 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004079 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004080 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004081 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004082 }
4083
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004084 /* Got Conf Rsp PENDING from remote side and asume we sent
4085 Conf Rsp PENDING in the code above */
4086 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004087 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004088
4089 /* check compatibility */
4090
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004091 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004092 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004093 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4094 else
4095 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004096 }
4097
Linus Torvalds1da177e2005-04-16 15:20:36 -07004098unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004099 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004100 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004101}
4102
Gustavo Padovan2d792812012-10-06 10:07:01 +01004103static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004104 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4105 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004106{
4107 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4108 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004109 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004110 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004111 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004112
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004113 if (cmd_len < sizeof(*rsp))
4114 return -EPROTO;
4115
Linus Torvalds1da177e2005-04-16 15:20:36 -07004116 scid = __le16_to_cpu(rsp->scid);
4117 flags = __le16_to_cpu(rsp->flags);
4118 result = __le16_to_cpu(rsp->result);
4119
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004120 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4121 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004122
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004123 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004124 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004125 return 0;
4126
4127 switch (result) {
4128 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004129 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004130 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004131 break;
4132
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004133 case L2CAP_CONF_PENDING:
4134 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4135
4136 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4137 char buf[64];
4138
4139 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004140 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004141 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004142 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004143 goto done;
4144 }
4145
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004146 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004147 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4148 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004149 } else {
4150 if (l2cap_check_efs(chan)) {
4151 amp_create_logical_link(chan);
4152 chan->ident = cmd->ident;
4153 }
4154 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004155 }
4156 goto done;
4157
Linus Torvalds1da177e2005-04-16 15:20:36 -07004158 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004159 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004160 char req[64];
4161
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004162 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004163 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004164 goto done;
4165 }
4166
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004167 /* throw out any old stored conf requests */
4168 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004169 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004170 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004171 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004172 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004173 goto done;
4174 }
4175
4176 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004177 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004178 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004179 if (result != L2CAP_CONF_SUCCESS)
4180 goto done;
4181 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004182 }
4183
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004184 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004185 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004186
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004187 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004188 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004189 goto done;
4190 }
4191
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004192 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004193 goto done;
4194
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004195 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004196
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004197 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004198 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004199
Mat Martineau105bdf92012-04-27 16:50:48 -07004200 if (chan->mode == L2CAP_MODE_ERTM ||
4201 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004202 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004203
Mat Martineau3c588192012-04-11 10:48:42 -07004204 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004205 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004206 else
4207 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004208 }
4209
4210done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004211 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004212 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004213}
4214
Gustavo Padovan2d792812012-10-06 10:07:01 +01004215static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004216 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4217 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004218{
4219 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4220 struct l2cap_disconn_rsp rsp;
4221 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004222 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004223
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004224 if (cmd_len != sizeof(*req))
4225 return -EPROTO;
4226
Linus Torvalds1da177e2005-04-16 15:20:36 -07004227 scid = __le16_to_cpu(req->scid);
4228 dcid = __le16_to_cpu(req->dcid);
4229
4230 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4231
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004232 mutex_lock(&conn->chan_lock);
4233
4234 chan = __l2cap_get_chan_by_scid(conn, dcid);
4235 if (!chan) {
4236 mutex_unlock(&conn->chan_lock);
Johan Hedberg662d6522013-10-16 11:20:47 +03004237 cmd_reject_invalid_cid(conn, cmd->ident, dcid, scid);
4238 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004239 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004240
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004241 l2cap_chan_lock(chan);
4242
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004243 rsp.dcid = cpu_to_le16(chan->scid);
4244 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004245 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4246
Gustavo Padovan5ec1bbe2013-10-15 19:24:48 -03004247 chan->ops->set_shutdown(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004248
Mat Martineau61d6ef32012-04-27 16:50:50 -07004249 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004250 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004251
4252 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004253
Gustavo Padovan80b98022012-05-27 22:27:51 -03004254 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004255 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004256
4257 mutex_unlock(&conn->chan_lock);
4258
Linus Torvalds1da177e2005-04-16 15:20:36 -07004259 return 0;
4260}
4261
Gustavo Padovan2d792812012-10-06 10:07:01 +01004262static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004263 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4264 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004265{
4266 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4267 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004268 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004269
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004270 if (cmd_len != sizeof(*rsp))
4271 return -EPROTO;
4272
Linus Torvalds1da177e2005-04-16 15:20:36 -07004273 scid = __le16_to_cpu(rsp->scid);
4274 dcid = __le16_to_cpu(rsp->dcid);
4275
4276 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4277
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004278 mutex_lock(&conn->chan_lock);
4279
4280 chan = __l2cap_get_chan_by_scid(conn, scid);
4281 if (!chan) {
4282 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004283 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004284 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004285
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004286 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004287
Mat Martineau61d6ef32012-04-27 16:50:50 -07004288 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004289 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004290
4291 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004292
Gustavo Padovan80b98022012-05-27 22:27:51 -03004293 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004294 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004295
4296 mutex_unlock(&conn->chan_lock);
4297
Linus Torvalds1da177e2005-04-16 15:20:36 -07004298 return 0;
4299}
4300
Gustavo Padovan2d792812012-10-06 10:07:01 +01004301static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004302 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4303 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004304{
4305 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004306 u16 type;
4307
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004308 if (cmd_len != sizeof(*req))
4309 return -EPROTO;
4310
Linus Torvalds1da177e2005-04-16 15:20:36 -07004311 type = __le16_to_cpu(req->type);
4312
4313 BT_DBG("type 0x%4.4x", type);
4314
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004315 if (type == L2CAP_IT_FEAT_MASK) {
4316 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004317 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004318 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004319 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4320 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004321 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004322 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004323 | L2CAP_FEAT_FCS;
Marcel Holtmann848566b2013-10-01 22:59:22 -07004324 if (conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004325 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004326 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004327
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004328 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004329 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4330 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004331 } else if (type == L2CAP_IT_FIXED_CHAN) {
4332 u8 buf[12];
4333 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004334
Marcel Holtmann848566b2013-10-01 22:59:22 -07004335 if (conn->hs_enabled)
Mat Martineau50a147c2011-11-02 16:18:34 -07004336 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4337 else
4338 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4339
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004340 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4341 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004342 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004343 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4344 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004345 } else {
4346 struct l2cap_info_rsp rsp;
4347 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004348 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004349 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4350 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004351 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004352
4353 return 0;
4354}
4355
Gustavo Padovan2d792812012-10-06 10:07:01 +01004356static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004357 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4358 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004359{
4360 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4361 u16 type, result;
4362
Jaganath Kanakkassery3f6fa3d2013-06-21 19:55:11 +05304363 if (cmd_len < sizeof(*rsp))
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004364 return -EPROTO;
4365
Linus Torvalds1da177e2005-04-16 15:20:36 -07004366 type = __le16_to_cpu(rsp->type);
4367 result = __le16_to_cpu(rsp->result);
4368
4369 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4370
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004371 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4372 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004373 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004374 return 0;
4375
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004376 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004377
Ville Tervoadb08ed2010-08-04 09:43:33 +03004378 if (result != L2CAP_IR_SUCCESS) {
4379 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4380 conn->info_ident = 0;
4381
4382 l2cap_conn_start(conn);
4383
4384 return 0;
4385 }
4386
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004387 switch (type) {
4388 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004389 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004390
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004391 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004392 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004393 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004394
4395 conn->info_ident = l2cap_get_ident(conn);
4396
4397 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004398 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004399 } else {
4400 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4401 conn->info_ident = 0;
4402
4403 l2cap_conn_start(conn);
4404 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004405 break;
4406
4407 case L2CAP_IT_FIXED_CHAN:
4408 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004409 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004410 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004411
4412 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004413 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004414 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004415
Linus Torvalds1da177e2005-04-16 15:20:36 -07004416 return 0;
4417}
4418
Mat Martineau17009152012-10-23 15:24:07 -07004419static int l2cap_create_channel_req(struct l2cap_conn *conn,
4420 struct l2cap_cmd_hdr *cmd,
4421 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004422{
4423 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004424 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004425 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004426 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004427 u16 psm, scid;
4428
4429 if (cmd_len != sizeof(*req))
4430 return -EPROTO;
4431
Marcel Holtmann848566b2013-10-01 22:59:22 -07004432 if (!conn->hs_enabled)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004433 return -EINVAL;
4434
4435 psm = le16_to_cpu(req->psm);
4436 scid = le16_to_cpu(req->scid);
4437
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004438 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 -07004439
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004440 /* For controller id 0 make BR/EDR connection */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004441 if (req->amp_id == AMP_ID_BREDR) {
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004442 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4443 req->amp_id);
4444 return 0;
4445 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004446
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004447 /* Validate AMP controller id */
4448 hdev = hci_dev_get(req->amp_id);
4449 if (!hdev)
4450 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004451
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004452 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004453 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004454 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004455 }
4456
4457 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4458 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004459 if (chan) {
4460 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4461 struct hci_conn *hs_hcon;
4462
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07004463 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
4464 &conn->hcon->dst);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004465 if (!hs_hcon) {
4466 hci_dev_put(hdev);
Johan Hedberg662d6522013-10-16 11:20:47 +03004467 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4468 chan->dcid);
4469 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004470 }
4471
4472 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4473
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004474 mgr->bredr_chan = chan;
4475 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004476 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004477 conn->mtu = hdev->block_mtu;
4478 }
4479
4480 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004481
4482 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004483
4484error:
4485 rsp.dcid = 0;
4486 rsp.scid = cpu_to_le16(scid);
4487 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4488 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4489
4490 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4491 sizeof(rsp), &rsp);
4492
Johan Hedbergdc280802013-09-16 13:05:13 +03004493 return 0;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004494}
4495
Mat Martineau8eb200b2012-10-23 15:24:17 -07004496static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4497{
4498 struct l2cap_move_chan_req req;
4499 u8 ident;
4500
4501 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4502
4503 ident = l2cap_get_ident(chan->conn);
4504 chan->ident = ident;
4505
4506 req.icid = cpu_to_le16(chan->scid);
4507 req.dest_amp_id = dest_amp_id;
4508
4509 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4510 &req);
4511
4512 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4513}
4514
Mat Martineau1500109b2012-10-23 15:24:15 -07004515static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004516{
4517 struct l2cap_move_chan_rsp rsp;
4518
Mat Martineau1500109b2012-10-23 15:24:15 -07004519 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004520
Mat Martineau1500109b2012-10-23 15:24:15 -07004521 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004522 rsp.result = cpu_to_le16(result);
4523
Mat Martineau1500109b2012-10-23 15:24:15 -07004524 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4525 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004526}
4527
Mat Martineau5b155ef2012-10-23 15:24:14 -07004528static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004529{
4530 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004531
Mat Martineau5b155ef2012-10-23 15:24:14 -07004532 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004533
Mat Martineau5b155ef2012-10-23 15:24:14 -07004534 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004535
Mat Martineau5b155ef2012-10-23 15:24:14 -07004536 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004537 cfm.result = cpu_to_le16(result);
4538
Mat Martineau5b155ef2012-10-23 15:24:14 -07004539 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4540 sizeof(cfm), &cfm);
4541
4542 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4543}
4544
4545static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4546{
4547 struct l2cap_move_chan_cfm cfm;
4548
4549 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4550
4551 cfm.icid = cpu_to_le16(icid);
4552 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4553
4554 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4555 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004556}
4557
4558static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004559 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004560{
4561 struct l2cap_move_chan_cfm_rsp rsp;
4562
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004563 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004564
4565 rsp.icid = cpu_to_le16(icid);
4566 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4567}
4568
Mat Martineau5f3847a2012-10-23 15:24:12 -07004569static void __release_logical_link(struct l2cap_chan *chan)
4570{
4571 chan->hs_hchan = NULL;
4572 chan->hs_hcon = NULL;
4573
4574 /* Placeholder - release the logical link */
4575}
4576
Mat Martineau1500109b2012-10-23 15:24:15 -07004577static void l2cap_logical_fail(struct l2cap_chan *chan)
4578{
4579 /* Logical link setup failed */
4580 if (chan->state != BT_CONNECTED) {
4581 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004582 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004583 return;
4584 }
4585
4586 switch (chan->move_role) {
4587 case L2CAP_MOVE_ROLE_RESPONDER:
4588 l2cap_move_done(chan);
4589 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4590 break;
4591 case L2CAP_MOVE_ROLE_INITIATOR:
4592 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4593 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4594 /* Remote has only sent pending or
4595 * success responses, clean up
4596 */
4597 l2cap_move_done(chan);
4598 }
4599
4600 /* Other amp move states imply that the move
4601 * has already aborted
4602 */
4603 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4604 break;
4605 }
4606}
4607
4608static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4609 struct hci_chan *hchan)
4610{
4611 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004612
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004613 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004614 chan->hs_hcon->l2cap_data = chan->conn;
4615
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004616 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004617
4618 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004619 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004620
4621 set_default_fcs(chan);
4622
4623 err = l2cap_ertm_init(chan);
4624 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004625 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004626 else
4627 l2cap_chan_ready(chan);
4628 }
4629}
4630
4631static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4632 struct hci_chan *hchan)
4633{
4634 chan->hs_hcon = hchan->conn;
4635 chan->hs_hcon->l2cap_data = chan->conn;
4636
4637 BT_DBG("move_state %d", chan->move_state);
4638
4639 switch (chan->move_state) {
4640 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4641 /* Move confirm will be sent after a success
4642 * response is received
4643 */
4644 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4645 break;
4646 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4647 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4648 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4649 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4650 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4651 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4652 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4653 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4654 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4655 }
4656 break;
4657 default:
4658 /* Move was not in expected state, free the channel */
4659 __release_logical_link(chan);
4660
4661 chan->move_state = L2CAP_MOVE_STABLE;
4662 }
4663}
4664
4665/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004666void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4667 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004668{
Mat Martineau1500109b2012-10-23 15:24:15 -07004669 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4670
4671 if (status) {
4672 l2cap_logical_fail(chan);
4673 __release_logical_link(chan);
4674 return;
4675 }
4676
4677 if (chan->state != BT_CONNECTED) {
4678 /* Ignore logical link if channel is on BR/EDR */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004679 if (chan->local_amp_id != AMP_ID_BREDR)
Mat Martineau1500109b2012-10-23 15:24:15 -07004680 l2cap_logical_finish_create(chan, hchan);
4681 } else {
4682 l2cap_logical_finish_move(chan, hchan);
4683 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004684}
4685
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004686void l2cap_move_start(struct l2cap_chan *chan)
4687{
4688 BT_DBG("chan %p", chan);
4689
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004690 if (chan->local_amp_id == AMP_ID_BREDR) {
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004691 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4692 return;
4693 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4694 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4695 /* Placeholder - start physical link setup */
4696 } else {
4697 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4698 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4699 chan->move_id = 0;
4700 l2cap_move_setup(chan);
4701 l2cap_send_move_chan_req(chan, 0);
4702 }
4703}
4704
Mat Martineau8eb200b2012-10-23 15:24:17 -07004705static void l2cap_do_create(struct l2cap_chan *chan, int result,
4706 u8 local_amp_id, u8 remote_amp_id)
4707{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004708 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4709 local_amp_id, remote_amp_id);
4710
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004711 chan->fcs = L2CAP_FCS_NONE;
4712
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004713 /* Outgoing channel on AMP */
4714 if (chan->state == BT_CONNECT) {
4715 if (result == L2CAP_CR_SUCCESS) {
4716 chan->local_amp_id = local_amp_id;
4717 l2cap_send_create_chan_req(chan, remote_amp_id);
4718 } else {
4719 /* Revert to BR/EDR connect */
4720 l2cap_send_conn_req(chan);
4721 }
4722
4723 return;
4724 }
4725
4726 /* Incoming channel on AMP */
4727 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004728 struct l2cap_conn_rsp rsp;
4729 char buf[128];
4730 rsp.scid = cpu_to_le16(chan->dcid);
4731 rsp.dcid = cpu_to_le16(chan->scid);
4732
Mat Martineau8eb200b2012-10-23 15:24:17 -07004733 if (result == L2CAP_CR_SUCCESS) {
4734 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004735 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4736 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004737 } else {
4738 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004739 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4740 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004741 }
4742
4743 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4744 sizeof(rsp), &rsp);
4745
4746 if (result == L2CAP_CR_SUCCESS) {
4747 __l2cap_state_change(chan, BT_CONFIG);
4748 set_bit(CONF_REQ_SENT, &chan->conf_state);
4749 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4750 L2CAP_CONF_REQ,
4751 l2cap_build_conf_req(chan, buf), buf);
4752 chan->num_conf_req++;
4753 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004754 }
4755}
4756
4757static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4758 u8 remote_amp_id)
4759{
4760 l2cap_move_setup(chan);
4761 chan->move_id = local_amp_id;
4762 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4763
4764 l2cap_send_move_chan_req(chan, remote_amp_id);
4765}
4766
4767static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4768{
4769 struct hci_chan *hchan = NULL;
4770
4771 /* Placeholder - get hci_chan for logical link */
4772
4773 if (hchan) {
4774 if (hchan->state == BT_CONNECTED) {
4775 /* Logical link is ready to go */
4776 chan->hs_hcon = hchan->conn;
4777 chan->hs_hcon->l2cap_data = chan->conn;
4778 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4779 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4780
4781 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4782 } else {
4783 /* Wait for logical link to be ready */
4784 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4785 }
4786 } else {
4787 /* Logical link not available */
4788 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4789 }
4790}
4791
4792static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4793{
4794 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4795 u8 rsp_result;
4796 if (result == -EINVAL)
4797 rsp_result = L2CAP_MR_BAD_ID;
4798 else
4799 rsp_result = L2CAP_MR_NOT_ALLOWED;
4800
4801 l2cap_send_move_chan_rsp(chan, rsp_result);
4802 }
4803
4804 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4805 chan->move_state = L2CAP_MOVE_STABLE;
4806
4807 /* Restart data transmission */
4808 l2cap_ertm_send(chan);
4809}
4810
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004811/* Invoke with locked chan */
4812void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004813{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004814 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004815 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004816
Mat Martineau8eb200b2012-10-23 15:24:17 -07004817 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4818 chan, result, local_amp_id, remote_amp_id);
4819
Mat Martineau8eb200b2012-10-23 15:24:17 -07004820 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4821 l2cap_chan_unlock(chan);
4822 return;
4823 }
4824
4825 if (chan->state != BT_CONNECTED) {
4826 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4827 } else if (result != L2CAP_MR_SUCCESS) {
4828 l2cap_do_move_cancel(chan, result);
4829 } else {
4830 switch (chan->move_role) {
4831 case L2CAP_MOVE_ROLE_INITIATOR:
4832 l2cap_do_move_initiate(chan, local_amp_id,
4833 remote_amp_id);
4834 break;
4835 case L2CAP_MOVE_ROLE_RESPONDER:
4836 l2cap_do_move_respond(chan, result);
4837 break;
4838 default:
4839 l2cap_do_move_cancel(chan, result);
4840 break;
4841 }
4842 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004843}
4844
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004845static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004846 struct l2cap_cmd_hdr *cmd,
4847 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004848{
4849 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004850 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004851 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004852 u16 icid = 0;
4853 u16 result = L2CAP_MR_NOT_ALLOWED;
4854
4855 if (cmd_len != sizeof(*req))
4856 return -EPROTO;
4857
4858 icid = le16_to_cpu(req->icid);
4859
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004860 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004861
Marcel Holtmann848566b2013-10-01 22:59:22 -07004862 if (!conn->hs_enabled)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004863 return -EINVAL;
4864
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004865 chan = l2cap_get_chan_by_dcid(conn, icid);
4866 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004867 rsp.icid = cpu_to_le16(icid);
4868 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4869 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4870 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004871 return 0;
4872 }
4873
Mat Martineau1500109b2012-10-23 15:24:15 -07004874 chan->ident = cmd->ident;
4875
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004876 if (chan->scid < L2CAP_CID_DYN_START ||
4877 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4878 (chan->mode != L2CAP_MODE_ERTM &&
4879 chan->mode != L2CAP_MODE_STREAMING)) {
4880 result = L2CAP_MR_NOT_ALLOWED;
4881 goto send_move_response;
4882 }
4883
4884 if (chan->local_amp_id == req->dest_amp_id) {
4885 result = L2CAP_MR_SAME_ID;
4886 goto send_move_response;
4887 }
4888
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004889 if (req->dest_amp_id != AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004890 struct hci_dev *hdev;
4891 hdev = hci_dev_get(req->dest_amp_id);
4892 if (!hdev || hdev->dev_type != HCI_AMP ||
4893 !test_bit(HCI_UP, &hdev->flags)) {
4894 if (hdev)
4895 hci_dev_put(hdev);
4896
4897 result = L2CAP_MR_BAD_ID;
4898 goto send_move_response;
4899 }
4900 hci_dev_put(hdev);
4901 }
4902
4903 /* Detect a move collision. Only send a collision response
4904 * if this side has "lost", otherwise proceed with the move.
4905 * The winner has the larger bd_addr.
4906 */
4907 if ((__chan_is_moving(chan) ||
4908 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
Marcel Holtmann6f59b902013-10-13 05:24:01 -07004909 bacmp(&conn->hcon->src, &conn->hcon->dst) > 0) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004910 result = L2CAP_MR_COLLISION;
4911 goto send_move_response;
4912 }
4913
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004914 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4915 l2cap_move_setup(chan);
4916 chan->move_id = req->dest_amp_id;
4917 icid = chan->dcid;
4918
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004919 if (req->dest_amp_id == AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004920 /* Moving to BR/EDR */
4921 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4922 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4923 result = L2CAP_MR_PEND;
4924 } else {
4925 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4926 result = L2CAP_MR_SUCCESS;
4927 }
4928 } else {
4929 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4930 /* Placeholder - uncomment when amp functions are available */
4931 /*amp_accept_physical(chan, req->dest_amp_id);*/
4932 result = L2CAP_MR_PEND;
4933 }
4934
4935send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004936 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004937
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004938 l2cap_chan_unlock(chan);
4939
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004940 return 0;
4941}
4942
Mat Martineau5b155ef2012-10-23 15:24:14 -07004943static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4944{
4945 struct l2cap_chan *chan;
4946 struct hci_chan *hchan = NULL;
4947
4948 chan = l2cap_get_chan_by_scid(conn, icid);
4949 if (!chan) {
4950 l2cap_send_move_chan_cfm_icid(conn, icid);
4951 return;
4952 }
4953
4954 __clear_chan_timer(chan);
4955 if (result == L2CAP_MR_PEND)
4956 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4957
4958 switch (chan->move_state) {
4959 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4960 /* Move confirm will be sent when logical link
4961 * is complete.
4962 */
4963 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4964 break;
4965 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4966 if (result == L2CAP_MR_PEND) {
4967 break;
4968 } else if (test_bit(CONN_LOCAL_BUSY,
4969 &chan->conn_state)) {
4970 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4971 } else {
4972 /* Logical link is up or moving to BR/EDR,
4973 * proceed with move
4974 */
4975 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4976 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4977 }
4978 break;
4979 case L2CAP_MOVE_WAIT_RSP:
4980 /* Moving to AMP */
4981 if (result == L2CAP_MR_SUCCESS) {
4982 /* Remote is ready, send confirm immediately
4983 * after logical link is ready
4984 */
4985 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4986 } else {
4987 /* Both logical link and move success
4988 * are required to confirm
4989 */
4990 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
4991 }
4992
4993 /* Placeholder - get hci_chan for logical link */
4994 if (!hchan) {
4995 /* Logical link not available */
4996 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4997 break;
4998 }
4999
5000 /* If the logical link is not yet connected, do not
5001 * send confirmation.
5002 */
5003 if (hchan->state != BT_CONNECTED)
5004 break;
5005
5006 /* Logical link is already ready to go */
5007
5008 chan->hs_hcon = hchan->conn;
5009 chan->hs_hcon->l2cap_data = chan->conn;
5010
5011 if (result == L2CAP_MR_SUCCESS) {
5012 /* Can confirm now */
5013 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5014 } else {
5015 /* Now only need move success
5016 * to confirm
5017 */
5018 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
5019 }
5020
5021 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5022 break;
5023 default:
5024 /* Any other amp move state means the move failed. */
5025 chan->move_id = chan->local_amp_id;
5026 l2cap_move_done(chan);
5027 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5028 }
5029
5030 l2cap_chan_unlock(chan);
5031}
5032
5033static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5034 u16 result)
5035{
5036 struct l2cap_chan *chan;
5037
5038 chan = l2cap_get_chan_by_ident(conn, ident);
5039 if (!chan) {
5040 /* Could not locate channel, icid is best guess */
5041 l2cap_send_move_chan_cfm_icid(conn, icid);
5042 return;
5043 }
5044
5045 __clear_chan_timer(chan);
5046
5047 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5048 if (result == L2CAP_MR_COLLISION) {
5049 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5050 } else {
5051 /* Cleanup - cancel move */
5052 chan->move_id = chan->local_amp_id;
5053 l2cap_move_done(chan);
5054 }
5055 }
5056
5057 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5058
5059 l2cap_chan_unlock(chan);
5060}
5061
5062static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5063 struct l2cap_cmd_hdr *cmd,
5064 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005065{
5066 struct l2cap_move_chan_rsp *rsp = data;
5067 u16 icid, result;
5068
5069 if (cmd_len != sizeof(*rsp))
5070 return -EPROTO;
5071
5072 icid = le16_to_cpu(rsp->icid);
5073 result = le16_to_cpu(rsp->result);
5074
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005075 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005076
Mat Martineau5b155ef2012-10-23 15:24:14 -07005077 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5078 l2cap_move_continue(conn, icid, result);
5079 else
5080 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005081
5082 return 0;
5083}
5084
Mat Martineau5f3847a2012-10-23 15:24:12 -07005085static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5086 struct l2cap_cmd_hdr *cmd,
5087 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005088{
5089 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005090 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005091 u16 icid, result;
5092
5093 if (cmd_len != sizeof(*cfm))
5094 return -EPROTO;
5095
5096 icid = le16_to_cpu(cfm->icid);
5097 result = le16_to_cpu(cfm->result);
5098
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005099 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005100
Mat Martineau5f3847a2012-10-23 15:24:12 -07005101 chan = l2cap_get_chan_by_dcid(conn, icid);
5102 if (!chan) {
5103 /* Spec requires a response even if the icid was not found */
5104 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5105 return 0;
5106 }
5107
5108 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5109 if (result == L2CAP_MC_CONFIRMED) {
5110 chan->local_amp_id = chan->move_id;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005111 if (chan->local_amp_id == AMP_ID_BREDR)
Mat Martineau5f3847a2012-10-23 15:24:12 -07005112 __release_logical_link(chan);
5113 } else {
5114 chan->move_id = chan->local_amp_id;
5115 }
5116
5117 l2cap_move_done(chan);
5118 }
5119
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005120 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5121
Mat Martineau5f3847a2012-10-23 15:24:12 -07005122 l2cap_chan_unlock(chan);
5123
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005124 return 0;
5125}
5126
5127static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005128 struct l2cap_cmd_hdr *cmd,
5129 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005130{
5131 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005132 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005133 u16 icid;
5134
5135 if (cmd_len != sizeof(*rsp))
5136 return -EPROTO;
5137
5138 icid = le16_to_cpu(rsp->icid);
5139
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005140 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005141
Mat Martineau3fd71a02012-10-23 15:24:16 -07005142 chan = l2cap_get_chan_by_scid(conn, icid);
5143 if (!chan)
5144 return 0;
5145
5146 __clear_chan_timer(chan);
5147
5148 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5149 chan->local_amp_id = chan->move_id;
5150
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005151 if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan)
Mat Martineau3fd71a02012-10-23 15:24:16 -07005152 __release_logical_link(chan);
5153
5154 l2cap_move_done(chan);
5155 }
5156
5157 l2cap_chan_unlock(chan);
5158
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005159 return 0;
5160}
5161
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005162static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005163 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005164{
5165 u16 max_latency;
5166
5167 if (min > max || min < 6 || max > 3200)
5168 return -EINVAL;
5169
5170 if (to_multiplier < 10 || to_multiplier > 3200)
5171 return -EINVAL;
5172
5173 if (max >= to_multiplier * 8)
5174 return -EINVAL;
5175
5176 max_latency = (to_multiplier * 8 / max) - 1;
5177 if (latency > 499 || latency > max_latency)
5178 return -EINVAL;
5179
5180 return 0;
5181}
5182
5183static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005184 struct l2cap_cmd_hdr *cmd,
5185 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005186{
5187 struct hci_conn *hcon = conn->hcon;
5188 struct l2cap_conn_param_update_req *req;
5189 struct l2cap_conn_param_update_rsp rsp;
5190 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005191 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005192
5193 if (!(hcon->link_mode & HCI_LM_MASTER))
5194 return -EINVAL;
5195
5196 cmd_len = __le16_to_cpu(cmd->len);
5197 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5198 return -EPROTO;
5199
5200 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005201 min = __le16_to_cpu(req->min);
5202 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005203 latency = __le16_to_cpu(req->latency);
5204 to_multiplier = __le16_to_cpu(req->to_multiplier);
5205
5206 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 +01005207 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005208
5209 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005210
5211 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5212 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005213 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005214 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005215 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005216
5217 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005218 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005219
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005220 if (!err)
5221 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5222
Claudio Takahaside731152011-02-11 19:28:55 -02005223 return 0;
5224}
5225
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005226static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005227 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5228 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005229{
5230 int err = 0;
5231
5232 switch (cmd->code) {
5233 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005234 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005235 break;
5236
5237 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005238 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005239 break;
5240
5241 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005242 case L2CAP_CREATE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005243 l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005244 break;
5245
5246 case L2CAP_CONF_REQ:
5247 err = l2cap_config_req(conn, cmd, cmd_len, data);
5248 break;
5249
5250 case L2CAP_CONF_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005251 l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005252 break;
5253
5254 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005255 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005256 break;
5257
5258 case L2CAP_DISCONN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005259 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005260 break;
5261
5262 case L2CAP_ECHO_REQ:
5263 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5264 break;
5265
5266 case L2CAP_ECHO_RSP:
5267 break;
5268
5269 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005270 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005271 break;
5272
5273 case L2CAP_INFO_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005274 l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005275 break;
5276
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005277 case L2CAP_CREATE_CHAN_REQ:
5278 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5279 break;
5280
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005281 case L2CAP_MOVE_CHAN_REQ:
5282 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5283 break;
5284
5285 case L2CAP_MOVE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005286 l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005287 break;
5288
5289 case L2CAP_MOVE_CHAN_CFM:
5290 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5291 break;
5292
5293 case L2CAP_MOVE_CHAN_CFM_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005294 l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005295 break;
5296
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005297 default:
5298 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5299 err = -EINVAL;
5300 break;
5301 }
5302
5303 return err;
5304}
5305
5306static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005307 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005308{
5309 switch (cmd->code) {
5310 case L2CAP_COMMAND_REJ:
5311 return 0;
5312
5313 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02005314 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005315
5316 case L2CAP_CONN_PARAM_UPDATE_RSP:
5317 return 0;
5318
5319 default:
5320 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5321 return -EINVAL;
5322 }
5323}
5324
Johan Hedbergc5623552013-04-29 19:35:33 +03005325static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5326 struct sk_buff *skb)
5327{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005328 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005329 struct l2cap_cmd_hdr *cmd;
5330 u16 len;
Johan Hedbergc5623552013-04-29 19:35:33 +03005331 int err;
5332
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005333 if (hcon->type != LE_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005334 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005335
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005336 if (skb->len < L2CAP_CMD_HDR_SIZE)
5337 goto drop;
Johan Hedbergc5623552013-04-29 19:35:33 +03005338
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005339 cmd = (void *) skb->data;
5340 skb_pull(skb, L2CAP_CMD_HDR_SIZE);
Johan Hedbergc5623552013-04-29 19:35:33 +03005341
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005342 len = le16_to_cpu(cmd->len);
Johan Hedbergc5623552013-04-29 19:35:33 +03005343
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005344 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, cmd->ident);
Johan Hedbergc5623552013-04-29 19:35:33 +03005345
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005346 if (len != skb->len || !cmd->ident) {
5347 BT_DBG("corrupted command");
5348 goto drop;
5349 }
Johan Hedbergc5623552013-04-29 19:35:33 +03005350
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005351 err = l2cap_le_sig_cmd(conn, cmd, skb->data);
5352 if (err) {
5353 struct l2cap_cmd_rej_unk rej;
Johan Hedbergc5623552013-04-29 19:35:33 +03005354
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005355 BT_ERR("Wrong link type (%d)", err);
Johan Hedbergc5623552013-04-29 19:35:33 +03005356
Johan Hedberga5211492013-10-16 11:20:49 +03005357 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005358 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
5359 sizeof(rej), &rej);
Johan Hedbergc5623552013-04-29 19:35:33 +03005360 }
5361
Marcel Holtmann3b166292013-10-02 08:28:21 -07005362drop:
Johan Hedbergc5623552013-04-29 19:35:33 +03005363 kfree_skb(skb);
5364}
5365
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005366static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005367 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005368{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005369 struct hci_conn *hcon = conn->hcon;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005370 u8 *data = skb->data;
5371 int len = skb->len;
5372 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005373 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005374
5375 l2cap_raw_recv(conn, skb);
5376
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005377 if (hcon->type != ACL_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005378 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005379
Linus Torvalds1da177e2005-04-16 15:20:36 -07005380 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005381 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005382 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5383 data += L2CAP_CMD_HDR_SIZE;
5384 len -= L2CAP_CMD_HDR_SIZE;
5385
Al Viro88219a02007-07-29 00:17:25 -07005386 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005387
Gustavo Padovan2d792812012-10-06 10:07:01 +01005388 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5389 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005390
Al Viro88219a02007-07-29 00:17:25 -07005391 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005392 BT_DBG("corrupted command");
5393 break;
5394 }
5395
Johan Hedbergc5623552013-04-29 19:35:33 +03005396 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005397 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005398 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005399
5400 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005401
Johan Hedberga5211492013-10-16 11:20:49 +03005402 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005403 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5404 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005405 }
5406
Al Viro88219a02007-07-29 00:17:25 -07005407 data += cmd_len;
5408 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005409 }
5410
Marcel Holtmann3b166292013-10-02 08:28:21 -07005411drop:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005412 kfree_skb(skb);
5413}
5414
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005415static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005416{
5417 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005418 int hdr_size;
5419
5420 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5421 hdr_size = L2CAP_EXT_HDR_SIZE;
5422 else
5423 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005424
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005425 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005426 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005427 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5428 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5429
5430 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005431 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005432 }
5433 return 0;
5434}
5435
Mat Martineau6ea00482012-05-17 20:53:52 -07005436static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005437{
Mat Martineaue31f7632012-05-17 20:53:41 -07005438 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005439
Mat Martineaue31f7632012-05-17 20:53:41 -07005440 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005441
Mat Martineaue31f7632012-05-17 20:53:41 -07005442 memset(&control, 0, sizeof(control));
5443 control.sframe = 1;
5444 control.final = 1;
5445 control.reqseq = chan->buffer_seq;
5446 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005447
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005448 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005449 control.super = L2CAP_SUPER_RNR;
5450 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005451 }
5452
Mat Martineaue31f7632012-05-17 20:53:41 -07005453 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5454 chan->unacked_frames > 0)
5455 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005456
Mat Martineaue31f7632012-05-17 20:53:41 -07005457 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005458 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005459
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005460 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005461 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5462 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5463 * send it now.
5464 */
5465 control.super = L2CAP_SUPER_RR;
5466 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005467 }
5468}
5469
Gustavo Padovan2d792812012-10-06 10:07:01 +01005470static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5471 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005472{
Mat Martineau84084a32011-07-22 14:54:00 -07005473 /* skb->len reflects data in skb as well as all fragments
5474 * skb->data_len reflects only data in fragments
5475 */
5476 if (!skb_has_frag_list(skb))
5477 skb_shinfo(skb)->frag_list = new_frag;
5478
5479 new_frag->next = NULL;
5480
5481 (*last_frag)->next = new_frag;
5482 *last_frag = new_frag;
5483
5484 skb->len += new_frag->len;
5485 skb->data_len += new_frag->len;
5486 skb->truesize += new_frag->truesize;
5487}
5488
Mat Martineau4b51dae92012-05-17 20:53:37 -07005489static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5490 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005491{
5492 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005493
Mat Martineau4b51dae92012-05-17 20:53:37 -07005494 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005495 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005496 if (chan->sdu)
5497 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005498
Gustavo Padovan80b98022012-05-27 22:27:51 -03005499 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005500 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005501
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005502 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005503 if (chan->sdu)
5504 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005505
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005506 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005507 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005508
Mat Martineau84084a32011-07-22 14:54:00 -07005509 if (chan->sdu_len > chan->imtu) {
5510 err = -EMSGSIZE;
5511 break;
5512 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005513
Mat Martineau84084a32011-07-22 14:54:00 -07005514 if (skb->len >= chan->sdu_len)
5515 break;
5516
5517 chan->sdu = skb;
5518 chan->sdu_last_frag = skb;
5519
5520 skb = NULL;
5521 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005522 break;
5523
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005524 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005525 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005526 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005527
Mat Martineau84084a32011-07-22 14:54:00 -07005528 append_skb_frag(chan->sdu, skb,
5529 &chan->sdu_last_frag);
5530 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005531
Mat Martineau84084a32011-07-22 14:54:00 -07005532 if (chan->sdu->len >= chan->sdu_len)
5533 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005534
Mat Martineau84084a32011-07-22 14:54:00 -07005535 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005536 break;
5537
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005538 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005539 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005540 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005541
Mat Martineau84084a32011-07-22 14:54:00 -07005542 append_skb_frag(chan->sdu, skb,
5543 &chan->sdu_last_frag);
5544 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005545
Mat Martineau84084a32011-07-22 14:54:00 -07005546 if (chan->sdu->len != chan->sdu_len)
5547 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005548
Gustavo Padovan80b98022012-05-27 22:27:51 -03005549 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005550
Mat Martineau84084a32011-07-22 14:54:00 -07005551 if (!err) {
5552 /* Reassembly complete */
5553 chan->sdu = NULL;
5554 chan->sdu_last_frag = NULL;
5555 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005556 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005557 break;
5558 }
5559
Mat Martineau84084a32011-07-22 14:54:00 -07005560 if (err) {
5561 kfree_skb(skb);
5562 kfree_skb(chan->sdu);
5563 chan->sdu = NULL;
5564 chan->sdu_last_frag = NULL;
5565 chan->sdu_len = 0;
5566 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005567
Mat Martineau84084a32011-07-22 14:54:00 -07005568 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005569}
5570
Mat Martineau32b32732012-10-23 15:24:11 -07005571static int l2cap_resegment(struct l2cap_chan *chan)
5572{
5573 /* Placeholder */
5574 return 0;
5575}
5576
Mat Martineaue3281402011-07-07 09:39:02 -07005577void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132eb2010-06-21 19:39:50 -03005578{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005579 u8 event;
5580
5581 if (chan->mode != L2CAP_MODE_ERTM)
5582 return;
5583
5584 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005585 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005586}
5587
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005588static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5589{
Mat Martineau63838722012-05-17 20:53:45 -07005590 int err = 0;
5591 /* Pass sequential frames to l2cap_reassemble_sdu()
5592 * until a gap is encountered.
5593 */
5594
5595 BT_DBG("chan %p", chan);
5596
5597 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5598 struct sk_buff *skb;
5599 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5600 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5601
5602 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5603
5604 if (!skb)
5605 break;
5606
5607 skb_unlink(skb, &chan->srej_q);
5608 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5609 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5610 if (err)
5611 break;
5612 }
5613
5614 if (skb_queue_empty(&chan->srej_q)) {
5615 chan->rx_state = L2CAP_RX_STATE_RECV;
5616 l2cap_send_ack(chan);
5617 }
5618
5619 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005620}
5621
5622static void l2cap_handle_srej(struct l2cap_chan *chan,
5623 struct l2cap_ctrl *control)
5624{
Mat Martineauf80842a2012-05-17 20:53:46 -07005625 struct sk_buff *skb;
5626
5627 BT_DBG("chan %p, control %p", chan, control);
5628
5629 if (control->reqseq == chan->next_tx_seq) {
5630 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005631 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005632 return;
5633 }
5634
5635 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5636
5637 if (skb == NULL) {
5638 BT_DBG("Seq %d not available for retransmission",
5639 control->reqseq);
5640 return;
5641 }
5642
5643 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5644 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005645 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005646 return;
5647 }
5648
5649 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5650
5651 if (control->poll) {
5652 l2cap_pass_to_tx(chan, control);
5653
5654 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5655 l2cap_retransmit(chan, control);
5656 l2cap_ertm_send(chan);
5657
5658 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5659 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5660 chan->srej_save_reqseq = control->reqseq;
5661 }
5662 } else {
5663 l2cap_pass_to_tx_fbit(chan, control);
5664
5665 if (control->final) {
5666 if (chan->srej_save_reqseq != control->reqseq ||
5667 !test_and_clear_bit(CONN_SREJ_ACT,
5668 &chan->conn_state))
5669 l2cap_retransmit(chan, control);
5670 } else {
5671 l2cap_retransmit(chan, control);
5672 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5673 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5674 chan->srej_save_reqseq = control->reqseq;
5675 }
5676 }
5677 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005678}
5679
5680static void l2cap_handle_rej(struct l2cap_chan *chan,
5681 struct l2cap_ctrl *control)
5682{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005683 struct sk_buff *skb;
5684
5685 BT_DBG("chan %p, control %p", chan, control);
5686
5687 if (control->reqseq == chan->next_tx_seq) {
5688 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005689 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005690 return;
5691 }
5692
5693 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5694
5695 if (chan->max_tx && skb &&
5696 bt_cb(skb)->control.retries >= chan->max_tx) {
5697 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005698 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005699 return;
5700 }
5701
5702 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5703
5704 l2cap_pass_to_tx(chan, control);
5705
5706 if (control->final) {
5707 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5708 l2cap_retransmit_all(chan, control);
5709 } else {
5710 l2cap_retransmit_all(chan, control);
5711 l2cap_ertm_send(chan);
5712 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5713 set_bit(CONN_REJ_ACT, &chan->conn_state);
5714 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005715}
5716
Mat Martineau4b51dae92012-05-17 20:53:37 -07005717static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5718{
5719 BT_DBG("chan %p, txseq %d", chan, txseq);
5720
5721 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5722 chan->expected_tx_seq);
5723
5724 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5725 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005726 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005727 /* See notes below regarding "double poll" and
5728 * invalid packets.
5729 */
5730 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5731 BT_DBG("Invalid/Ignore - after SREJ");
5732 return L2CAP_TXSEQ_INVALID_IGNORE;
5733 } else {
5734 BT_DBG("Invalid - in window after SREJ sent");
5735 return L2CAP_TXSEQ_INVALID;
5736 }
5737 }
5738
5739 if (chan->srej_list.head == txseq) {
5740 BT_DBG("Expected SREJ");
5741 return L2CAP_TXSEQ_EXPECTED_SREJ;
5742 }
5743
5744 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5745 BT_DBG("Duplicate SREJ - txseq already stored");
5746 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5747 }
5748
5749 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5750 BT_DBG("Unexpected SREJ - not requested");
5751 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5752 }
5753 }
5754
5755 if (chan->expected_tx_seq == txseq) {
5756 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5757 chan->tx_win) {
5758 BT_DBG("Invalid - txseq outside tx window");
5759 return L2CAP_TXSEQ_INVALID;
5760 } else {
5761 BT_DBG("Expected");
5762 return L2CAP_TXSEQ_EXPECTED;
5763 }
5764 }
5765
5766 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01005767 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005768 BT_DBG("Duplicate - expected_tx_seq later than txseq");
5769 return L2CAP_TXSEQ_DUPLICATE;
5770 }
5771
5772 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
5773 /* A source of invalid packets is a "double poll" condition,
5774 * where delays cause us to send multiple poll packets. If
5775 * the remote stack receives and processes both polls,
5776 * sequence numbers can wrap around in such a way that a
5777 * resent frame has a sequence number that looks like new data
5778 * with a sequence gap. This would trigger an erroneous SREJ
5779 * request.
5780 *
5781 * Fortunately, this is impossible with a tx window that's
5782 * less than half of the maximum sequence number, which allows
5783 * invalid frames to be safely ignored.
5784 *
5785 * With tx window sizes greater than half of the tx window
5786 * maximum, the frame is invalid and cannot be ignored. This
5787 * causes a disconnect.
5788 */
5789
5790 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5791 BT_DBG("Invalid/Ignore - txseq outside tx window");
5792 return L2CAP_TXSEQ_INVALID_IGNORE;
5793 } else {
5794 BT_DBG("Invalid - txseq outside tx window");
5795 return L2CAP_TXSEQ_INVALID;
5796 }
5797 } else {
5798 BT_DBG("Unexpected - txseq indicates missing frames");
5799 return L2CAP_TXSEQ_UNEXPECTED;
5800 }
5801}
5802
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005803static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5804 struct l2cap_ctrl *control,
5805 struct sk_buff *skb, u8 event)
5806{
5807 int err = 0;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005808 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005809
5810 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5811 event);
5812
5813 switch (event) {
5814 case L2CAP_EV_RECV_IFRAME:
5815 switch (l2cap_classify_txseq(chan, control->txseq)) {
5816 case L2CAP_TXSEQ_EXPECTED:
5817 l2cap_pass_to_tx(chan, control);
5818
5819 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5820 BT_DBG("Busy, discarding expected seq %d",
5821 control->txseq);
5822 break;
5823 }
5824
5825 chan->expected_tx_seq = __next_seq(chan,
5826 control->txseq);
5827
5828 chan->buffer_seq = chan->expected_tx_seq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005829 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005830
5831 err = l2cap_reassemble_sdu(chan, skb, control);
5832 if (err)
5833 break;
5834
5835 if (control->final) {
5836 if (!test_and_clear_bit(CONN_REJ_ACT,
5837 &chan->conn_state)) {
5838 control->final = 0;
5839 l2cap_retransmit_all(chan, control);
5840 l2cap_ertm_send(chan);
5841 }
5842 }
5843
5844 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5845 l2cap_send_ack(chan);
5846 break;
5847 case L2CAP_TXSEQ_UNEXPECTED:
5848 l2cap_pass_to_tx(chan, control);
5849
5850 /* Can't issue SREJ frames in the local busy state.
5851 * Drop this frame, it will be seen as missing
5852 * when local busy is exited.
5853 */
5854 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5855 BT_DBG("Busy, discarding unexpected seq %d",
5856 control->txseq);
5857 break;
5858 }
5859
5860 /* There was a gap in the sequence, so an SREJ
5861 * must be sent for each missing frame. The
5862 * current frame is stored for later use.
5863 */
5864 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005865 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005866 BT_DBG("Queued %p (queue len %d)", skb,
5867 skb_queue_len(&chan->srej_q));
5868
5869 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5870 l2cap_seq_list_clear(&chan->srej_list);
5871 l2cap_send_srej(chan, control->txseq);
5872
5873 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5874 break;
5875 case L2CAP_TXSEQ_DUPLICATE:
5876 l2cap_pass_to_tx(chan, control);
5877 break;
5878 case L2CAP_TXSEQ_INVALID_IGNORE:
5879 break;
5880 case L2CAP_TXSEQ_INVALID:
5881 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005882 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005883 break;
5884 }
5885 break;
5886 case L2CAP_EV_RECV_RR:
5887 l2cap_pass_to_tx(chan, control);
5888 if (control->final) {
5889 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5890
Mat Martineaue6a3ee62012-10-23 15:24:22 -07005891 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
5892 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005893 control->final = 0;
5894 l2cap_retransmit_all(chan, control);
5895 }
5896
5897 l2cap_ertm_send(chan);
5898 } else if (control->poll) {
5899 l2cap_send_i_or_rr_or_rnr(chan);
5900 } else {
5901 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5902 &chan->conn_state) &&
5903 chan->unacked_frames)
5904 __set_retrans_timer(chan);
5905
5906 l2cap_ertm_send(chan);
5907 }
5908 break;
5909 case L2CAP_EV_RECV_RNR:
5910 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5911 l2cap_pass_to_tx(chan, control);
5912 if (control && control->poll) {
5913 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5914 l2cap_send_rr_or_rnr(chan, 0);
5915 }
5916 __clear_retrans_timer(chan);
5917 l2cap_seq_list_clear(&chan->retrans_list);
5918 break;
5919 case L2CAP_EV_RECV_REJ:
5920 l2cap_handle_rej(chan, control);
5921 break;
5922 case L2CAP_EV_RECV_SREJ:
5923 l2cap_handle_srej(chan, control);
5924 break;
5925 default:
5926 break;
5927 }
5928
5929 if (skb && !skb_in_use) {
5930 BT_DBG("Freeing %p", skb);
5931 kfree_skb(skb);
5932 }
5933
5934 return err;
5935}
5936
5937static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5938 struct l2cap_ctrl *control,
5939 struct sk_buff *skb, u8 event)
5940{
5941 int err = 0;
5942 u16 txseq = control->txseq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005943 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005944
5945 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5946 event);
5947
5948 switch (event) {
5949 case L2CAP_EV_RECV_IFRAME:
5950 switch (l2cap_classify_txseq(chan, txseq)) {
5951 case L2CAP_TXSEQ_EXPECTED:
5952 /* Keep frame for reassembly later */
5953 l2cap_pass_to_tx(chan, control);
5954 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005955 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005956 BT_DBG("Queued %p (queue len %d)", skb,
5957 skb_queue_len(&chan->srej_q));
5958
5959 chan->expected_tx_seq = __next_seq(chan, txseq);
5960 break;
5961 case L2CAP_TXSEQ_EXPECTED_SREJ:
5962 l2cap_seq_list_pop(&chan->srej_list);
5963
5964 l2cap_pass_to_tx(chan, control);
5965 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005966 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005967 BT_DBG("Queued %p (queue len %d)", skb,
5968 skb_queue_len(&chan->srej_q));
5969
5970 err = l2cap_rx_queued_iframes(chan);
5971 if (err)
5972 break;
5973
5974 break;
5975 case L2CAP_TXSEQ_UNEXPECTED:
5976 /* Got a frame that can't be reassembled yet.
5977 * Save it for later, and send SREJs to cover
5978 * the missing frames.
5979 */
5980 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005981 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005982 BT_DBG("Queued %p (queue len %d)", skb,
5983 skb_queue_len(&chan->srej_q));
5984
5985 l2cap_pass_to_tx(chan, control);
5986 l2cap_send_srej(chan, control->txseq);
5987 break;
5988 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
5989 /* This frame was requested with an SREJ, but
5990 * some expected retransmitted frames are
5991 * missing. Request retransmission of missing
5992 * SREJ'd frames.
5993 */
5994 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005995 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005996 BT_DBG("Queued %p (queue len %d)", skb,
5997 skb_queue_len(&chan->srej_q));
5998
5999 l2cap_pass_to_tx(chan, control);
6000 l2cap_send_srej_list(chan, control->txseq);
6001 break;
6002 case L2CAP_TXSEQ_DUPLICATE_SREJ:
6003 /* We've already queued this frame. Drop this copy. */
6004 l2cap_pass_to_tx(chan, control);
6005 break;
6006 case L2CAP_TXSEQ_DUPLICATE:
6007 /* Expecting a later sequence number, so this frame
6008 * was already received. Ignore it completely.
6009 */
6010 break;
6011 case L2CAP_TXSEQ_INVALID_IGNORE:
6012 break;
6013 case L2CAP_TXSEQ_INVALID:
6014 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006015 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006016 break;
6017 }
6018 break;
6019 case L2CAP_EV_RECV_RR:
6020 l2cap_pass_to_tx(chan, control);
6021 if (control->final) {
6022 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6023
6024 if (!test_and_clear_bit(CONN_REJ_ACT,
6025 &chan->conn_state)) {
6026 control->final = 0;
6027 l2cap_retransmit_all(chan, control);
6028 }
6029
6030 l2cap_ertm_send(chan);
6031 } else if (control->poll) {
6032 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6033 &chan->conn_state) &&
6034 chan->unacked_frames) {
6035 __set_retrans_timer(chan);
6036 }
6037
6038 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6039 l2cap_send_srej_tail(chan);
6040 } else {
6041 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6042 &chan->conn_state) &&
6043 chan->unacked_frames)
6044 __set_retrans_timer(chan);
6045
6046 l2cap_send_ack(chan);
6047 }
6048 break;
6049 case L2CAP_EV_RECV_RNR:
6050 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6051 l2cap_pass_to_tx(chan, control);
6052 if (control->poll) {
6053 l2cap_send_srej_tail(chan);
6054 } else {
6055 struct l2cap_ctrl rr_control;
6056 memset(&rr_control, 0, sizeof(rr_control));
6057 rr_control.sframe = 1;
6058 rr_control.super = L2CAP_SUPER_RR;
6059 rr_control.reqseq = chan->buffer_seq;
6060 l2cap_send_sframe(chan, &rr_control);
6061 }
6062
6063 break;
6064 case L2CAP_EV_RECV_REJ:
6065 l2cap_handle_rej(chan, control);
6066 break;
6067 case L2CAP_EV_RECV_SREJ:
6068 l2cap_handle_srej(chan, control);
6069 break;
6070 }
6071
6072 if (skb && !skb_in_use) {
6073 BT_DBG("Freeing %p", skb);
6074 kfree_skb(skb);
6075 }
6076
6077 return err;
6078}
6079
Mat Martineau32b32732012-10-23 15:24:11 -07006080static int l2cap_finish_move(struct l2cap_chan *chan)
6081{
6082 BT_DBG("chan %p", chan);
6083
6084 chan->rx_state = L2CAP_RX_STATE_RECV;
6085
6086 if (chan->hs_hcon)
6087 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6088 else
6089 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6090
6091 return l2cap_resegment(chan);
6092}
6093
6094static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6095 struct l2cap_ctrl *control,
6096 struct sk_buff *skb, u8 event)
6097{
6098 int err;
6099
6100 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6101 event);
6102
6103 if (!control->poll)
6104 return -EPROTO;
6105
6106 l2cap_process_reqseq(chan, control->reqseq);
6107
6108 if (!skb_queue_empty(&chan->tx_q))
6109 chan->tx_send_head = skb_peek(&chan->tx_q);
6110 else
6111 chan->tx_send_head = NULL;
6112
6113 /* Rewind next_tx_seq to the point expected
6114 * by the receiver.
6115 */
6116 chan->next_tx_seq = control->reqseq;
6117 chan->unacked_frames = 0;
6118
6119 err = l2cap_finish_move(chan);
6120 if (err)
6121 return err;
6122
6123 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6124 l2cap_send_i_or_rr_or_rnr(chan);
6125
6126 if (event == L2CAP_EV_RECV_IFRAME)
6127 return -EPROTO;
6128
6129 return l2cap_rx_state_recv(chan, control, NULL, event);
6130}
6131
6132static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6133 struct l2cap_ctrl *control,
6134 struct sk_buff *skb, u8 event)
6135{
6136 int err;
6137
6138 if (!control->final)
6139 return -EPROTO;
6140
6141 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6142
6143 chan->rx_state = L2CAP_RX_STATE_RECV;
6144 l2cap_process_reqseq(chan, control->reqseq);
6145
6146 if (!skb_queue_empty(&chan->tx_q))
6147 chan->tx_send_head = skb_peek(&chan->tx_q);
6148 else
6149 chan->tx_send_head = NULL;
6150
6151 /* Rewind next_tx_seq to the point expected
6152 * by the receiver.
6153 */
6154 chan->next_tx_seq = control->reqseq;
6155 chan->unacked_frames = 0;
6156
6157 if (chan->hs_hcon)
6158 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6159 else
6160 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6161
6162 err = l2cap_resegment(chan);
6163
6164 if (!err)
6165 err = l2cap_rx_state_recv(chan, control, skb, event);
6166
6167 return err;
6168}
6169
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006170static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6171{
6172 /* Make sure reqseq is for a packet that has been sent but not acked */
6173 u16 unacked;
6174
6175 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6176 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6177}
6178
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006179static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6180 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006181{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006182 int err = 0;
6183
6184 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6185 control, skb, event, chan->rx_state);
6186
6187 if (__valid_reqseq(chan, control->reqseq)) {
6188 switch (chan->rx_state) {
6189 case L2CAP_RX_STATE_RECV:
6190 err = l2cap_rx_state_recv(chan, control, skb, event);
6191 break;
6192 case L2CAP_RX_STATE_SREJ_SENT:
6193 err = l2cap_rx_state_srej_sent(chan, control, skb,
6194 event);
6195 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006196 case L2CAP_RX_STATE_WAIT_P:
6197 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6198 break;
6199 case L2CAP_RX_STATE_WAIT_F:
6200 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6201 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006202 default:
6203 /* shut it down */
6204 break;
6205 }
6206 } else {
6207 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6208 control->reqseq, chan->next_tx_seq,
6209 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006210 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006211 }
6212
6213 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006214}
6215
6216static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6217 struct sk_buff *skb)
6218{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006219 int err = 0;
6220
6221 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6222 chan->rx_state);
6223
6224 if (l2cap_classify_txseq(chan, control->txseq) ==
6225 L2CAP_TXSEQ_EXPECTED) {
6226 l2cap_pass_to_tx(chan, control);
6227
6228 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6229 __next_seq(chan, chan->buffer_seq));
6230
6231 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6232
6233 l2cap_reassemble_sdu(chan, skb, control);
6234 } else {
6235 if (chan->sdu) {
6236 kfree_skb(chan->sdu);
6237 chan->sdu = NULL;
6238 }
6239 chan->sdu_last_frag = NULL;
6240 chan->sdu_len = 0;
6241
6242 if (skb) {
6243 BT_DBG("Freeing %p", skb);
6244 kfree_skb(skb);
6245 }
6246 }
6247
6248 chan->last_acked_seq = control->txseq;
6249 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6250
6251 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006252}
6253
6254static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6255{
6256 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6257 u16 len;
6258 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006259
Mat Martineaub76bbd62012-04-11 10:48:43 -07006260 __unpack_control(chan, skb);
6261
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006262 len = skb->len;
6263
6264 /*
6265 * We can just drop the corrupted I-frame here.
6266 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006267 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006268 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006269 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006270 goto drop;
6271
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006272 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006273 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006274
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006275 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006276 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006277
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006278 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006279 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006280 goto drop;
6281 }
6282
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006283 if (!control->sframe) {
6284 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006285
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006286 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6287 control->sar, control->reqseq, control->final,
6288 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006289
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006290 /* Validate F-bit - F=0 always valid, F=1 only
6291 * valid in TX WAIT_F
6292 */
6293 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006294 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006295
6296 if (chan->mode != L2CAP_MODE_STREAMING) {
6297 event = L2CAP_EV_RECV_IFRAME;
6298 err = l2cap_rx(chan, control, skb, event);
6299 } else {
6300 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006301 }
6302
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006303 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006304 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006305 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006306 const u8 rx_func_to_event[4] = {
6307 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6308 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6309 };
6310
6311 /* Only I-frames are expected in streaming mode */
6312 if (chan->mode == L2CAP_MODE_STREAMING)
6313 goto drop;
6314
6315 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6316 control->reqseq, control->final, control->poll,
6317 control->super);
6318
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006319 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006320 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006321 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006322 goto drop;
6323 }
6324
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006325 /* Validate F and P bits */
6326 if (control->final && (control->poll ||
6327 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6328 goto drop;
6329
6330 event = rx_func_to_event[control->super];
6331 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006332 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006333 }
6334
6335 return 0;
6336
6337drop:
6338 kfree_skb(skb);
6339 return 0;
6340}
6341
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006342static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6343 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006344{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006345 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006346
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006347 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006348 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006349 if (cid == L2CAP_CID_A2MP) {
6350 chan = a2mp_channel_create(conn, skb);
6351 if (!chan) {
6352 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006353 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006354 }
6355
6356 l2cap_chan_lock(chan);
6357 } else {
6358 BT_DBG("unknown cid 0x%4.4x", cid);
6359 /* Drop packet and return */
6360 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006361 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006362 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006363 }
6364
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006365 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006366
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006367 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006368 goto drop;
6369
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006370 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006371 case L2CAP_MODE_BASIC:
6372 /* If socket recv buffers overflows we drop data here
6373 * which is *bad* because L2CAP has to be reliable.
6374 * But we don't have any other choice. L2CAP doesn't
6375 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006376
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006377 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006378 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006379
Gustavo Padovan80b98022012-05-27 22:27:51 -03006380 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006381 goto done;
6382 break;
6383
6384 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006385 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006386 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006387 goto done;
6388
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006389 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006390 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006391 break;
6392 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006393
6394drop:
6395 kfree_skb(skb);
6396
6397done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006398 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006399}
6400
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006401static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6402 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006403{
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006404 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006405 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006406
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006407 if (hcon->type != ACL_LINK)
6408 goto drop;
6409
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006410 chan = l2cap_global_chan_by_psm(0, psm, &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006411 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006412 goto drop;
6413
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006414 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006415
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006416 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006417 goto drop;
6418
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006419 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006420 goto drop;
6421
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006422 /* Store remote BD_ADDR and PSM for msg_name */
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006423 bacpy(&bt_cb(skb)->bdaddr, &hcon->dst);
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006424 bt_cb(skb)->psm = psm;
6425
Gustavo Padovan80b98022012-05-27 22:27:51 -03006426 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006427 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006428
6429drop:
6430 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006431}
6432
Marcel Holtmann72f78352013-04-23 00:59:00 -07006433static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006434 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006435{
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006436 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006437 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006438
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006439 if (hcon->type != LE_LINK)
6440 goto drop;
6441
Johan Hedbergaf1c0132013-04-29 19:35:42 +03006442 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006443 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006444 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006445 goto drop;
6446
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006447 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006448
Marcel Holtmanncc8dba22013-10-18 03:43:01 -07006449 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, hcon->dst_type))
6450 goto drop;
6451
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006452 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006453 goto drop;
6454
Gustavo Padovan80b98022012-05-27 22:27:51 -03006455 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006456 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006457
6458drop:
6459 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006460}
6461
Linus Torvalds1da177e2005-04-16 15:20:36 -07006462static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6463{
6464 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006465 u16 cid, len;
6466 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006467
6468 skb_pull(skb, L2CAP_HDR_SIZE);
6469 cid = __le16_to_cpu(lh->cid);
6470 len = __le16_to_cpu(lh->len);
6471
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006472 if (len != skb->len) {
6473 kfree_skb(skb);
6474 return;
6475 }
6476
Linus Torvalds1da177e2005-04-16 15:20:36 -07006477 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6478
6479 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006480 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006481 l2cap_sig_channel(conn, skb);
6482 break;
6483
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006484 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006485 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006486 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006487 l2cap_conless_channel(conn, psm, skb);
6488 break;
6489
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006490 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006491 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006492 break;
6493
Marcel Holtmanna2877622013-10-02 23:46:54 -07006494 case L2CAP_CID_LE_SIGNALING:
6495 l2cap_le_sig_channel(conn, skb);
6496 break;
6497
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006498 case L2CAP_CID_SMP:
6499 if (smp_sig_channel(conn, skb))
6500 l2cap_conn_del(conn->hcon, EACCES);
6501 break;
6502
Linus Torvalds1da177e2005-04-16 15:20:36 -07006503 default:
6504 l2cap_data_channel(conn, cid, skb);
6505 break;
6506 }
6507}
6508
6509/* ---- L2CAP interface with lower layer (HCI) ---- */
6510
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006511int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006512{
6513 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006514 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006515
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006516 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006517
6518 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006519 read_lock(&chan_list_lock);
6520 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006521 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006522 continue;
6523
Marcel Holtmann7eafc592013-10-13 08:12:47 -07006524 if (!bacmp(&c->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006525 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006526 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006527 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006528 exact++;
Marcel Holtmann7eafc592013-10-13 08:12:47 -07006529 } else if (!bacmp(&c->src, BDADDR_ANY)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006530 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006531 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006532 lm2 |= HCI_LM_MASTER;
6533 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006534 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006535 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006536
6537 return exact ? lm1 : lm2;
6538}
6539
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006540void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006541{
Marcel Holtmann01394182006-07-03 10:02:46 +02006542 struct l2cap_conn *conn;
6543
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006544 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006545
Linus Torvalds1da177e2005-04-16 15:20:36 -07006546 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03006547 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006548 if (conn)
6549 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006550 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006551 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006552 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006553}
6554
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006555int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006556{
6557 struct l2cap_conn *conn = hcon->l2cap_data;
6558
6559 BT_DBG("hcon %p", hcon);
6560
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006561 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006562 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006563 return conn->disc_reason;
6564}
6565
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006566void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006567{
6568 BT_DBG("hcon %p reason %d", hcon, reason);
6569
Joe Perchese1750722011-06-29 18:18:29 -07006570 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006571}
6572
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006573static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006574{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006575 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006576 return;
6577
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006578 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006579 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006580 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006581 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006582 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006583 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006584 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006585 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006586 }
6587}
6588
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006589int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006590{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006591 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006592 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006593
Marcel Holtmann01394182006-07-03 10:02:46 +02006594 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006595 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006596
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006597 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006598
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006599 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306600 if (!status && encrypt)
6601 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006602 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006603 }
6604
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006605 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006606
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006607 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006608 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006609
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006610 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6611 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006612
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006613 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6614 l2cap_chan_unlock(chan);
6615 continue;
6616 }
6617
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006618 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006619 if (!status && encrypt) {
6620 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006621 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006622 }
6623
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006624 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006625 continue;
6626 }
6627
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006628 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006629 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006630 continue;
6631 }
6632
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006633 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006634 chan->state == BT_CONFIG)) {
Marcel Holtmannd97c8992013-10-14 02:53:54 -07006635 chan->ops->resume(chan);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006636 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006637 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006638 continue;
6639 }
6640
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006641 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006642 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006643 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006644 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006645 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006646 }
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03006647 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006648 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006649 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006650 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006651
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006652 lock_sock(sk);
6653
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006654 if (!status) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07006655 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006656 res = L2CAP_CR_PEND;
6657 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006658 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006659 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006660 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006661 res = L2CAP_CR_SUCCESS;
6662 stat = L2CAP_CS_NO_INFO;
6663 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006664 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006665 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006666 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006667 res = L2CAP_CR_SEC_BLOCK;
6668 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006669 }
6670
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006671 release_sock(sk);
6672
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006673 rsp.scid = cpu_to_le16(chan->dcid);
6674 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006675 rsp.result = cpu_to_le16(res);
6676 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006677 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006678 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006679
6680 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6681 res == L2CAP_CR_SUCCESS) {
6682 char buf[128];
6683 set_bit(CONF_REQ_SENT, &chan->conf_state);
6684 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6685 L2CAP_CONF_REQ,
6686 l2cap_build_conf_req(chan, buf),
6687 buf);
6688 chan->num_conf_req++;
6689 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006690 }
6691
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006692 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006693 }
6694
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006695 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006696
Linus Torvalds1da177e2005-04-16 15:20:36 -07006697 return 0;
6698}
6699
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006700int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006701{
6702 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006703 struct l2cap_hdr *hdr;
6704 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006705
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006706 /* For AMP controller do not create l2cap conn */
6707 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6708 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006709
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006710 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03006711 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006712
6713 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006714 goto drop;
6715
6716 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6717
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006718 switch (flags) {
6719 case ACL_START:
6720 case ACL_START_NO_FLUSH:
6721 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006722 if (conn->rx_len) {
6723 BT_ERR("Unexpected start frame (len %d)", skb->len);
6724 kfree_skb(conn->rx_skb);
6725 conn->rx_skb = NULL;
6726 conn->rx_len = 0;
6727 l2cap_conn_unreliable(conn, ECOMM);
6728 }
6729
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006730 /* Start fragment always begin with Basic L2CAP header */
6731 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006732 BT_ERR("Frame is too short (len %d)", skb->len);
6733 l2cap_conn_unreliable(conn, ECOMM);
6734 goto drop;
6735 }
6736
6737 hdr = (struct l2cap_hdr *) skb->data;
6738 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6739
6740 if (len == skb->len) {
6741 /* Complete frame received */
6742 l2cap_recv_frame(conn, skb);
6743 return 0;
6744 }
6745
6746 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6747
6748 if (skb->len > len) {
6749 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006750 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006751 l2cap_conn_unreliable(conn, ECOMM);
6752 goto drop;
6753 }
6754
6755 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006756 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006757 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006758 goto drop;
6759
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006760 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006761 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006762 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006763 break;
6764
6765 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006766 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6767
6768 if (!conn->rx_len) {
6769 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6770 l2cap_conn_unreliable(conn, ECOMM);
6771 goto drop;
6772 }
6773
6774 if (skb->len > conn->rx_len) {
6775 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006776 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006777 kfree_skb(conn->rx_skb);
6778 conn->rx_skb = NULL;
6779 conn->rx_len = 0;
6780 l2cap_conn_unreliable(conn, ECOMM);
6781 goto drop;
6782 }
6783
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006784 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006785 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006786 conn->rx_len -= skb->len;
6787
6788 if (!conn->rx_len) {
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02006789 /* Complete frame received. l2cap_recv_frame
6790 * takes ownership of the skb so set the global
6791 * rx_skb pointer to NULL first.
6792 */
6793 struct sk_buff *rx_skb = conn->rx_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006794 conn->rx_skb = NULL;
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02006795 l2cap_recv_frame(conn, rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006796 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006797 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006798 }
6799
6800drop:
6801 kfree_skb(skb);
6802 return 0;
6803}
6804
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006805static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006806{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006807 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006808
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006809 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006810
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006811 list_for_each_entry(c, &chan_list, global_l) {
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006812 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 -07006813 &c->src, &c->dst,
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006814 c->state, __le16_to_cpu(c->psm),
6815 c->scid, c->dcid, c->imtu, c->omtu,
6816 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006817 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006818
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006819 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006820
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006821 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006822}
6823
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006824static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6825{
6826 return single_open(file, l2cap_debugfs_show, inode->i_private);
6827}
6828
6829static const struct file_operations l2cap_debugfs_fops = {
6830 .open = l2cap_debugfs_open,
6831 .read = seq_read,
6832 .llseek = seq_lseek,
6833 .release = single_release,
6834};
6835
6836static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006837
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006838int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006839{
6840 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006841
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006842 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006843 if (err < 0)
6844 return err;
6845
Marcel Holtmann1120e4b2013-10-17 17:24:16 -07006846 if (IS_ERR_OR_NULL(bt_debugfs))
6847 return 0;
6848
6849 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6850 NULL, &l2cap_debugfs_fops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006851
Linus Torvalds1da177e2005-04-16 15:20:36 -07006852 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006853}
6854
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006855void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006856{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006857 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006858 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006859}
6860
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006861module_param(disable_ertm, bool, 0644);
6862MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");