blob: 72ce21a822f75fa48d0ee598964bcfa50bd660c9 [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. Padovan89bc5002011-06-03 00:19:47 -0300227{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200228 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100229 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200230
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300231 chan->state = state;
Gustavo Padovan53f52122013-10-15 19:24:45 -0300232 chan->ops->state_change(chan, state, 0);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300233}
234
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. Padovan89bc5002011-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. Padovan89bc5002011-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. Padovan89bc5002011-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. Padovan89bc5002011-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. Padovan89bc5002011-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. Padovan89bc5002011-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. Padovan89bc5002011-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. Padovan89bc5002011-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. Padovan89bc5002011-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{
Johan Hedberg60bac182013-04-29 19:35:41 +03001385 struct sock *parent;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001386 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001387
1388 BT_DBG("");
1389
1390 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001391 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Marcel Holtmann6f59b902013-10-13 05:24:01 -07001392 &conn->hcon->src, &conn->hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001393 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001394 return;
1395
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001396 /* Client ATT sockets should override the server one */
1397 if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
1398 return;
1399
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001400 parent = pchan->sk;
1401
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001402 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001403
Gustavo Padovan80b98022012-05-27 22:27:51 -03001404 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001405 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001406 goto clean;
1407
Johan Hedberg9f22398c2013-04-29 19:35:38 +03001408 chan->dcid = L2CAP_CID_ATT;
1409
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001410 bacpy(&chan->src, &conn->hcon->src);
1411 bacpy(&chan->dst, &conn->hcon->dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001412 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
1413 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
Ville Tervob62f3282011-02-10 22:38:50 -03001414
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001415 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001416
Ville Tervob62f3282011-02-10 22:38:50 -03001417clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001418 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001419}
1420
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001421static void l2cap_conn_ready(struct l2cap_conn *conn)
1422{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001423 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001424 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001425
1426 BT_DBG("conn %p", conn);
1427
Johan Hedbergd8729922013-04-29 19:35:39 +03001428 /* For outgoing pairing which doesn't necessarily have an
1429 * associated socket (e.g. mgmt_pair_device).
1430 */
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001431 if (hcon->out && hcon->type == LE_LINK)
1432 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001433
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001434 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001435
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001436 if (hcon->type == LE_LINK)
1437 l2cap_le_conn_ready(conn);
1438
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001439 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001440
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001441 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001442
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001443 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1444 l2cap_chan_unlock(chan);
1445 continue;
1446 }
1447
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001448 if (hcon->type == LE_LINK) {
1449 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001450 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001451
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001452 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo Padovan74e75742013-10-15 19:24:51 -03001453 l2cap_chan_ready(chan);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001454
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001455 } else if (chan->state == BT_CONNECT) {
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001456 l2cap_do_start(chan);
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001457 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001458
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001459 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001460 }
1461
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001462 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001463}
1464
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001465/* Notify sockets that we cannot guaranty reliability anymore */
1466static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1467{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001468 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001469
1470 BT_DBG("conn %p", conn);
1471
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001472 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001473
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001474 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001475 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001476 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001477 }
1478
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001479 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001480}
1481
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001482static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001483{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001484 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001485 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001486
Marcel Holtmann984947d2009-02-06 23:35:19 +01001487 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001488 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001489
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001490 l2cap_conn_start(conn);
1491}
1492
David Herrmann2c8e1412013-04-06 20:28:45 +02001493/*
1494 * l2cap_user
1495 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1496 * callback is called during registration. The ->remove callback is called
1497 * during unregistration.
1498 * An l2cap_user object can either be explicitly unregistered or when the
1499 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1500 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1501 * External modules must own a reference to the l2cap_conn object if they intend
1502 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1503 * any time if they don't.
1504 */
1505
1506int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1507{
1508 struct hci_dev *hdev = conn->hcon->hdev;
1509 int ret;
1510
1511 /* We need to check whether l2cap_conn is registered. If it is not, we
1512 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1513 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1514 * relies on the parent hci_conn object to be locked. This itself relies
1515 * on the hci_dev object to be locked. So we must lock the hci device
1516 * here, too. */
1517
1518 hci_dev_lock(hdev);
1519
1520 if (user->list.next || user->list.prev) {
1521 ret = -EINVAL;
1522 goto out_unlock;
1523 }
1524
1525 /* conn->hchan is NULL after l2cap_conn_del() was called */
1526 if (!conn->hchan) {
1527 ret = -ENODEV;
1528 goto out_unlock;
1529 }
1530
1531 ret = user->probe(conn, user);
1532 if (ret)
1533 goto out_unlock;
1534
1535 list_add(&user->list, &conn->users);
1536 ret = 0;
1537
1538out_unlock:
1539 hci_dev_unlock(hdev);
1540 return ret;
1541}
1542EXPORT_SYMBOL(l2cap_register_user);
1543
1544void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1545{
1546 struct hci_dev *hdev = conn->hcon->hdev;
1547
1548 hci_dev_lock(hdev);
1549
1550 if (!user->list.next || !user->list.prev)
1551 goto out_unlock;
1552
1553 list_del(&user->list);
1554 user->list.next = NULL;
1555 user->list.prev = NULL;
1556 user->remove(conn, user);
1557
1558out_unlock:
1559 hci_dev_unlock(hdev);
1560}
1561EXPORT_SYMBOL(l2cap_unregister_user);
1562
1563static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1564{
1565 struct l2cap_user *user;
1566
1567 while (!list_empty(&conn->users)) {
1568 user = list_first_entry(&conn->users, struct l2cap_user, list);
1569 list_del(&user->list);
1570 user->list.next = NULL;
1571 user->list.prev = NULL;
1572 user->remove(conn, user);
1573 }
1574}
1575
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001576static void l2cap_conn_del(struct hci_conn *hcon, int err)
1577{
1578 struct l2cap_conn *conn = hcon->l2cap_data;
1579 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001580
1581 if (!conn)
1582 return;
1583
1584 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1585
1586 kfree_skb(conn->rx_skb);
1587
David Herrmann2c8e1412013-04-06 20:28:45 +02001588 l2cap_unregister_all_users(conn);
1589
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001590 mutex_lock(&conn->chan_lock);
1591
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001592 /* Kill channels */
1593 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001594 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001595 l2cap_chan_lock(chan);
1596
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001597 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001598
1599 l2cap_chan_unlock(chan);
1600
Gustavo Padovan80b98022012-05-27 22:27:51 -03001601 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001602 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001603 }
1604
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001605 mutex_unlock(&conn->chan_lock);
1606
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001607 hci_chan_del(conn->hchan);
1608
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001609 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001610 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001611
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001612 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001613 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001614 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001615 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001616
1617 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001618 conn->hchan = NULL;
1619 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001620}
1621
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001622static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001623{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001624 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001625 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001626
Johan Hedbergd06cc412012-06-06 18:44:11 +08001627 BT_DBG("conn %p", conn);
1628
1629 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1630 smp_chan_destroy(conn);
1631 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1632 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001633}
1634
Claudio Takahasibaf43252013-04-11 13:55:50 -03001635static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636{
Marcel Holtmann01394182006-07-03 10:02:46 +02001637 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001638 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639
Claudio Takahasibaf43252013-04-11 13:55:50 -03001640 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641 return conn;
1642
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001643 hchan = hci_chan_create(hcon);
1644 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001645 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001646
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001647 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001648 if (!conn) {
1649 hci_chan_del(hchan);
1650 return NULL;
1651 }
1652
David Herrmann9c903e32013-04-06 20:28:44 +02001653 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654 hcon->l2cap_data = conn;
1655 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001656 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001657 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001659 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001660
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001661 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001662 case LE_LINK:
1663 if (hcon->hdev->le_mtu) {
1664 conn->mtu = hcon->hdev->le_mtu;
1665 break;
1666 }
1667 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001668 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001669 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001670 break;
1671 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001672
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001673 conn->feat_mask = 0;
1674
Marcel Holtmann848566b2013-10-01 22:59:22 -07001675 if (hcon->type == ACL_LINK)
1676 conn->hs_enabled = test_bit(HCI_HS_ENABLED,
1677 &hcon->hdev->dev_flags);
1678
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001680 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001681
1682 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001683 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001685 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001686 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001687 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001688 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001689
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001690 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001691
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692 return conn;
1693}
1694
David Herrmann9c903e32013-04-06 20:28:44 +02001695static void l2cap_conn_free(struct kref *ref)
1696{
1697 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1698
1699 hci_conn_put(conn->hcon);
1700 kfree(conn);
1701}
1702
1703void l2cap_conn_get(struct l2cap_conn *conn)
1704{
1705 kref_get(&conn->ref);
1706}
1707EXPORT_SYMBOL(l2cap_conn_get);
1708
1709void l2cap_conn_put(struct l2cap_conn *conn)
1710{
1711 kref_put(&conn->ref, l2cap_conn_free);
1712}
1713EXPORT_SYMBOL(l2cap_conn_put);
1714
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716
Ido Yarivc2287682012-04-20 15:46:07 -03001717/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 * Returns closest match.
1719 */
Ido Yarivc2287682012-04-20 15:46:07 -03001720static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1721 bdaddr_t *src,
1722 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001724 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001726 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001727
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001728 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001729 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730 continue;
1731
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001732 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001733 int src_match, dst_match;
1734 int src_any, dst_any;
1735
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736 /* Exact match. */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001737 src_match = !bacmp(&c->src, src);
1738 dst_match = !bacmp(&c->dst, dst);
Ido Yarivc2287682012-04-20 15:46:07 -03001739 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001740 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001741 return c;
1742 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743
1744 /* Closest match */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001745 src_any = !bacmp(&c->src, BDADDR_ANY);
1746 dst_any = !bacmp(&c->dst, BDADDR_ANY);
Ido Yarivc2287682012-04-20 15:46:07 -03001747 if ((src_match && dst_any) || (src_any && dst_match) ||
1748 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001749 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750 }
1751 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001753 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001754
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001755 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756}
1757
Andre Guedes8e9f9892012-04-24 21:02:55 -03001758int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1759 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761 struct l2cap_conn *conn;
1762 struct hci_conn *hcon;
1763 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001764 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001765 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001767 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301768 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001770 hdev = hci_get_route(dst, &chan->src);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001771 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772 return -EHOSTUNREACH;
1773
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001774 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001776 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001777
1778 /* PSM must be odd and lsb of upper byte must be 0 */
1779 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001780 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001781 err = -EINVAL;
1782 goto done;
1783 }
1784
1785 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1786 err = -EINVAL;
1787 goto done;
1788 }
1789
1790 switch (chan->mode) {
1791 case L2CAP_MODE_BASIC:
1792 break;
1793 case L2CAP_MODE_ERTM:
1794 case L2CAP_MODE_STREAMING:
1795 if (!disable_ertm)
1796 break;
1797 /* fall through */
1798 default:
1799 err = -ENOTSUPP;
1800 goto done;
1801 }
1802
Gustavo Padovan0797e012012-05-27 22:27:54 -03001803 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001804 case BT_CONNECT:
1805 case BT_CONNECT2:
1806 case BT_CONFIG:
1807 /* Already connecting */
1808 err = 0;
1809 goto done;
1810
1811 case BT_CONNECTED:
1812 /* Already connected */
1813 err = -EISCONN;
1814 goto done;
1815
1816 case BT_OPEN:
1817 case BT_BOUND:
1818 /* Can connect */
1819 break;
1820
1821 default:
1822 err = -EBADFD;
1823 goto done;
1824 }
1825
1826 /* Set destination address and psm */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001827 bacpy(&chan->dst, dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001828 chan->dst_type = dst_type;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001829
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001830 chan->psm = psm;
1831 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001833 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001834
Johan Hedbergf224ca52013-04-29 19:35:36 +03001835 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001836 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001837 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001838 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001839 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001840 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001841
Ville Tervo30e76272011-02-22 16:10:53 -03001842 if (IS_ERR(hcon)) {
1843 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001845 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846
Claudio Takahasibaf43252013-04-11 13:55:50 -03001847 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001849 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001850 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851 goto done;
1852 }
1853
Johan Hedberg141d5702013-04-29 19:35:37 +03001854 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1855 hci_conn_drop(hcon);
1856 err = -EBUSY;
1857 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001858 }
1859
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860 /* Update source addr of the socket */
Marcel Holtmann7eafc592013-10-13 08:12:47 -07001861 bacpy(&chan->src, &hcon->src);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07001862 chan->src_type = bdaddr_type(hcon, hcon->src_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001864 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001865 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001866 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001867
Johan Hedberg5ee98912013-04-29 19:35:43 +03001868 /* l2cap_chan_add takes its own ref so we can drop this one */
1869 hci_conn_drop(hcon);
1870
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001871 l2cap_state_change(chan, BT_CONNECT);
Gustavo Padovan8d836d72013-10-15 19:24:47 -03001872 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873
1874 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001875 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001876 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001877 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001878 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001879 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001880 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001881 }
1882
Ville Tervo30e76272011-02-22 16:10:53 -03001883 err = 0;
1884
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001886 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001887 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888 hci_dev_put(hdev);
1889 return err;
1890}
1891
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001892static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001893{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001894 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001895 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001896
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001897 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001898
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001899 l2cap_chan_lock(chan);
1900
Mat Martineau80909e02012-05-17 20:53:50 -07001901 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001902 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001903 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001904 return;
1905 }
1906
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001907 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001908
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001909 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001910 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001911}
1912
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001913static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001914{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001915 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001916 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001917
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001918 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001919
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001920 l2cap_chan_lock(chan);
1921
Mat Martineau80909e02012-05-17 20:53:50 -07001922 if (!chan->conn) {
1923 l2cap_chan_unlock(chan);
1924 l2cap_chan_put(chan);
1925 return;
1926 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001927
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001928 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001929 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001930 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001931}
1932
Gustavo Padovand6603662012-05-21 13:58:22 -03001933static void l2cap_streaming_send(struct l2cap_chan *chan,
1934 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001935{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001936 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001937 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001938
Mat Martineau37339372012-05-17 20:53:33 -07001939 BT_DBG("chan %p, skbs %p", chan, skbs);
1940
Mat Martineaub99e13a2012-10-23 15:24:19 -07001941 if (__chan_is_moving(chan))
1942 return;
1943
Mat Martineau37339372012-05-17 20:53:33 -07001944 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1945
1946 while (!skb_queue_empty(&chan->tx_q)) {
1947
1948 skb = skb_dequeue(&chan->tx_q);
1949
1950 bt_cb(skb)->control.retries = 1;
1951 control = &bt_cb(skb)->control;
1952
1953 control->reqseq = 0;
1954 control->txseq = chan->next_tx_seq;
1955
1956 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001957
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001958 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001959 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1960 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001961 }
1962
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001963 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001964
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001965 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001966
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001967 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001968 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001969 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001970}
1971
Szymon Janc67c9e842011-07-28 16:24:33 +02001972static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001973{
1974 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001975 struct l2cap_ctrl *control;
1976 int sent = 0;
1977
1978 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001979
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001980 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001981 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001982
Mat Martineau94122bb2012-05-02 09:42:02 -07001983 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1984 return 0;
1985
Mat Martineaub99e13a2012-10-23 15:24:19 -07001986 if (__chan_is_moving(chan))
1987 return 0;
1988
Mat Martineau18a48e72012-05-17 20:53:34 -07001989 while (chan->tx_send_head &&
1990 chan->unacked_frames < chan->remote_tx_win &&
1991 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001992
Mat Martineau18a48e72012-05-17 20:53:34 -07001993 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001994
Mat Martineau18a48e72012-05-17 20:53:34 -07001995 bt_cb(skb)->control.retries = 1;
1996 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001997
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001998 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001999 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03002000
Mat Martineau18a48e72012-05-17 20:53:34 -07002001 control->reqseq = chan->buffer_seq;
2002 chan->last_acked_seq = chan->buffer_seq;
2003 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002004
Mat Martineau18a48e72012-05-17 20:53:34 -07002005 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002006
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002007 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07002008 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2009 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002010 }
2011
Mat Martineau18a48e72012-05-17 20:53:34 -07002012 /* Clone after data has been modified. Data is assumed to be
2013 read-only (for locking purposes) on cloned sk_buffs.
2014 */
2015 tx_skb = skb_clone(skb, GFP_KERNEL);
2016
2017 if (!tx_skb)
2018 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002019
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002020 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002021
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002022 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002023 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002024 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002025 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002026
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002027 if (skb_queue_is_last(&chan->tx_q, skb))
2028 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002029 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002030 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002031
2032 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002033 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002034 }
2035
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002036 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2037 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002038
2039 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002040}
2041
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002042static void l2cap_ertm_resend(struct l2cap_chan *chan)
2043{
2044 struct l2cap_ctrl control;
2045 struct sk_buff *skb;
2046 struct sk_buff *tx_skb;
2047 u16 seq;
2048
2049 BT_DBG("chan %p", chan);
2050
2051 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2052 return;
2053
Mat Martineaub99e13a2012-10-23 15:24:19 -07002054 if (__chan_is_moving(chan))
2055 return;
2056
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002057 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2058 seq = l2cap_seq_list_pop(&chan->retrans_list);
2059
2060 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2061 if (!skb) {
2062 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002063 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002064 continue;
2065 }
2066
2067 bt_cb(skb)->control.retries++;
2068 control = bt_cb(skb)->control;
2069
2070 if (chan->max_tx != 0 &&
2071 bt_cb(skb)->control.retries > chan->max_tx) {
2072 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002073 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002074 l2cap_seq_list_clear(&chan->retrans_list);
2075 break;
2076 }
2077
2078 control.reqseq = chan->buffer_seq;
2079 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2080 control.final = 1;
2081 else
2082 control.final = 0;
2083
2084 if (skb_cloned(skb)) {
2085 /* Cloned sk_buffs are read-only, so we need a
2086 * writeable copy
2087 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002088 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002089 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002090 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002091 }
2092
2093 if (!tx_skb) {
2094 l2cap_seq_list_clear(&chan->retrans_list);
2095 break;
2096 }
2097
2098 /* Update skb contents */
2099 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2100 put_unaligned_le32(__pack_extended_control(&control),
2101 tx_skb->data + L2CAP_HDR_SIZE);
2102 } else {
2103 put_unaligned_le16(__pack_enhanced_control(&control),
2104 tx_skb->data + L2CAP_HDR_SIZE);
2105 }
2106
2107 if (chan->fcs == L2CAP_FCS_CRC16) {
2108 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2109 put_unaligned_le16(fcs, skb_put(tx_skb,
2110 L2CAP_FCS_SIZE));
2111 }
2112
2113 l2cap_do_send(chan, tx_skb);
2114
2115 BT_DBG("Resent txseq %d", control.txseq);
2116
2117 chan->last_acked_seq = chan->buffer_seq;
2118 }
2119}
2120
Mat Martineauf80842a2012-05-17 20:53:46 -07002121static void l2cap_retransmit(struct l2cap_chan *chan,
2122 struct l2cap_ctrl *control)
2123{
2124 BT_DBG("chan %p, control %p", chan, control);
2125
2126 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2127 l2cap_ertm_resend(chan);
2128}
2129
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002130static void l2cap_retransmit_all(struct l2cap_chan *chan,
2131 struct l2cap_ctrl *control)
2132{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002133 struct sk_buff *skb;
2134
2135 BT_DBG("chan %p, control %p", chan, control);
2136
2137 if (control->poll)
2138 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2139
2140 l2cap_seq_list_clear(&chan->retrans_list);
2141
2142 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2143 return;
2144
2145 if (chan->unacked_frames) {
2146 skb_queue_walk(&chan->tx_q, skb) {
2147 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002148 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002149 break;
2150 }
2151
2152 skb_queue_walk_from(&chan->tx_q, skb) {
2153 if (skb == chan->tx_send_head)
2154 break;
2155
2156 l2cap_seq_list_append(&chan->retrans_list,
2157 bt_cb(skb)->control.txseq);
2158 }
2159
2160 l2cap_ertm_resend(chan);
2161 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002162}
2163
Szymon Jancb17e73b2012-01-11 10:59:47 +01002164static void l2cap_send_ack(struct l2cap_chan *chan)
2165{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002166 struct l2cap_ctrl control;
2167 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2168 chan->last_acked_seq);
2169 int threshold;
2170
2171 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2172 chan, chan->last_acked_seq, chan->buffer_seq);
2173
2174 memset(&control, 0, sizeof(control));
2175 control.sframe = 1;
2176
2177 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2178 chan->rx_state == L2CAP_RX_STATE_RECV) {
2179 __clear_ack_timer(chan);
2180 control.super = L2CAP_SUPER_RNR;
2181 control.reqseq = chan->buffer_seq;
2182 l2cap_send_sframe(chan, &control);
2183 } else {
2184 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2185 l2cap_ertm_send(chan);
2186 /* If any i-frames were sent, they included an ack */
2187 if (chan->buffer_seq == chan->last_acked_seq)
2188 frames_to_ack = 0;
2189 }
2190
Mat Martineauc20f8e32012-07-10 05:47:07 -07002191 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002192 * Calculate without mul or div
2193 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002194 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002195 threshold += threshold << 1;
2196 threshold >>= 2;
2197
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002198 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002199 threshold);
2200
2201 if (frames_to_ack >= threshold) {
2202 __clear_ack_timer(chan);
2203 control.super = L2CAP_SUPER_RR;
2204 control.reqseq = chan->buffer_seq;
2205 l2cap_send_sframe(chan, &control);
2206 frames_to_ack = 0;
2207 }
2208
2209 if (frames_to_ack)
2210 __set_ack_timer(chan);
2211 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002212}
2213
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002214static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2215 struct msghdr *msg, int len,
2216 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002217{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002218 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002219 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002220 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002221
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002222 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002223 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002224
2225 sent += count;
2226 len -= count;
2227
2228 /* Continuation fragments (no L2CAP header) */
2229 frag = &skb_shinfo(skb)->frag_list;
2230 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002231 struct sk_buff *tmp;
2232
Linus Torvalds1da177e2005-04-16 15:20:36 -07002233 count = min_t(unsigned int, conn->mtu, len);
2234
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002235 tmp = chan->ops->alloc_skb(chan, count,
2236 msg->msg_flags & MSG_DONTWAIT);
2237 if (IS_ERR(tmp))
2238 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002239
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002240 *frag = tmp;
2241
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002242 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2243 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002244
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002245 (*frag)->priority = skb->priority;
2246
Linus Torvalds1da177e2005-04-16 15:20:36 -07002247 sent += count;
2248 len -= count;
2249
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002250 skb->len += (*frag)->len;
2251 skb->data_len += (*frag)->len;
2252
Linus Torvalds1da177e2005-04-16 15:20:36 -07002253 frag = &(*frag)->next;
2254 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255
2256 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002257}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002258
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002259static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002260 struct msghdr *msg, size_t len,
2261 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002262{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002263 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002264 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002265 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002266 struct l2cap_hdr *lh;
2267
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002268 BT_DBG("chan %p psm 0x%2.2x len %zu priority %u", chan,
2269 __le16_to_cpu(chan->psm), len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002270
2271 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002272
2273 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002274 msg->msg_flags & MSG_DONTWAIT);
2275 if (IS_ERR(skb))
2276 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002277
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002278 skb->priority = priority;
2279
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002280 /* Create L2CAP header */
2281 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002282 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002283 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
Marcel Holtmann43b1b8d2013-10-12 06:01:26 -07002284 put_unaligned(chan->psm, (__le16 *) skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002285
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002286 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002287 if (unlikely(err < 0)) {
2288 kfree_skb(skb);
2289 return ERR_PTR(err);
2290 }
2291 return skb;
2292}
2293
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002294static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002295 struct msghdr *msg, size_t len,
2296 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002297{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002298 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002299 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002300 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002301 struct l2cap_hdr *lh;
2302
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002303 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002304
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002305 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002306
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002307 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002308 msg->msg_flags & MSG_DONTWAIT);
2309 if (IS_ERR(skb))
2310 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002311
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002312 skb->priority = priority;
2313
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002314 /* Create L2CAP header */
2315 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002316 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002317 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002318
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002319 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002320 if (unlikely(err < 0)) {
2321 kfree_skb(skb);
2322 return ERR_PTR(err);
2323 }
2324 return skb;
2325}
2326
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002327static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002328 struct msghdr *msg, size_t len,
2329 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002330{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002331 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002332 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002333 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002334 struct l2cap_hdr *lh;
2335
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002336 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002337
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002338 if (!conn)
2339 return ERR_PTR(-ENOTCONN);
2340
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002341 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002342
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002343 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002344 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002345
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002346 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002347 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002348
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002349 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002350
2351 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002352 msg->msg_flags & MSG_DONTWAIT);
2353 if (IS_ERR(skb))
2354 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002355
2356 /* Create L2CAP header */
2357 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002358 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002359 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002360
Mat Martineau18a48e72012-05-17 20:53:34 -07002361 /* Control header is populated later */
2362 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2363 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2364 else
2365 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002366
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002367 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002368 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002369
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002370 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002371 if (unlikely(err < 0)) {
2372 kfree_skb(skb);
2373 return ERR_PTR(err);
2374 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002375
Mat Martineau18a48e72012-05-17 20:53:34 -07002376 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002377 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002378 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002379}
2380
Mat Martineau94122bb2012-05-02 09:42:02 -07002381static int l2cap_segment_sdu(struct l2cap_chan *chan,
2382 struct sk_buff_head *seg_queue,
2383 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002384{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002385 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002386 u16 sdu_len;
2387 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002388 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002389
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002390 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002391
Mat Martineau94122bb2012-05-02 09:42:02 -07002392 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2393 * so fragmented skbs are not used. The HCI layer's handling
2394 * of fragmented skbs is not compatible with ERTM's queueing.
2395 */
2396
2397 /* PDU size is derived from the HCI MTU */
2398 pdu_len = chan->conn->mtu;
2399
Mat Martineaua5495742012-10-23 15:24:21 -07002400 /* Constrain PDU size for BR/EDR connections */
2401 if (!chan->hs_hcon)
2402 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002403
2404 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002405 if (chan->fcs)
2406 pdu_len -= L2CAP_FCS_SIZE;
2407
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002408 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002409
2410 /* Remote device may have requested smaller PDUs */
2411 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2412
2413 if (len <= pdu_len) {
2414 sar = L2CAP_SAR_UNSEGMENTED;
2415 sdu_len = 0;
2416 pdu_len = len;
2417 } else {
2418 sar = L2CAP_SAR_START;
2419 sdu_len = len;
2420 pdu_len -= L2CAP_SDULEN_SIZE;
2421 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002422
2423 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002424 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002425
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002426 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002427 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002428 return PTR_ERR(skb);
2429 }
2430
Mat Martineau94122bb2012-05-02 09:42:02 -07002431 bt_cb(skb)->control.sar = sar;
2432 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002433
Mat Martineau94122bb2012-05-02 09:42:02 -07002434 len -= pdu_len;
2435 if (sdu_len) {
2436 sdu_len = 0;
2437 pdu_len += L2CAP_SDULEN_SIZE;
2438 }
2439
2440 if (len <= pdu_len) {
2441 sar = L2CAP_SAR_END;
2442 pdu_len = len;
2443 } else {
2444 sar = L2CAP_SAR_CONTINUE;
2445 }
2446 }
2447
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002448 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002449}
2450
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002451int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002452 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002453{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002454 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002455 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002456 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002457
2458 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002459 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002460 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002461 if (IS_ERR(skb))
2462 return PTR_ERR(skb);
2463
2464 l2cap_do_send(chan, skb);
2465 return len;
2466 }
2467
2468 switch (chan->mode) {
2469 case L2CAP_MODE_BASIC:
2470 /* Check outgoing MTU */
2471 if (len > chan->omtu)
2472 return -EMSGSIZE;
2473
2474 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002475 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002476 if (IS_ERR(skb))
2477 return PTR_ERR(skb);
2478
2479 l2cap_do_send(chan, skb);
2480 err = len;
2481 break;
2482
2483 case L2CAP_MODE_ERTM:
2484 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002485 /* Check outgoing MTU */
2486 if (len > chan->omtu) {
2487 err = -EMSGSIZE;
2488 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002489 }
2490
Mat Martineau94122bb2012-05-02 09:42:02 -07002491 __skb_queue_head_init(&seg_queue);
2492
2493 /* Do segmentation before calling in to the state machine,
2494 * since it's possible to block while waiting for memory
2495 * allocation.
2496 */
2497 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2498
2499 /* The channel could have been closed while segmenting,
2500 * check that it is still connected.
2501 */
2502 if (chan->state != BT_CONNECTED) {
2503 __skb_queue_purge(&seg_queue);
2504 err = -ENOTCONN;
2505 }
2506
2507 if (err)
2508 break;
2509
Mat Martineau37339372012-05-17 20:53:33 -07002510 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002511 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002512 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002513 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002514
Gustavo Padovand6603662012-05-21 13:58:22 -03002515 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002516
Mat Martineau94122bb2012-05-02 09:42:02 -07002517 /* If the skbs were not queued for sending, they'll still be in
2518 * seg_queue and need to be purged.
2519 */
2520 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002521 break;
2522
2523 default:
2524 BT_DBG("bad state %1.1x", chan->mode);
2525 err = -EBADFD;
2526 }
2527
2528 return err;
2529}
2530
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002531static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2532{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002533 struct l2cap_ctrl control;
2534 u16 seq;
2535
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002536 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002537
2538 memset(&control, 0, sizeof(control));
2539 control.sframe = 1;
2540 control.super = L2CAP_SUPER_SREJ;
2541
2542 for (seq = chan->expected_tx_seq; seq != txseq;
2543 seq = __next_seq(chan, seq)) {
2544 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2545 control.reqseq = seq;
2546 l2cap_send_sframe(chan, &control);
2547 l2cap_seq_list_append(&chan->srej_list, seq);
2548 }
2549 }
2550
2551 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002552}
2553
2554static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2555{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002556 struct l2cap_ctrl control;
2557
2558 BT_DBG("chan %p", chan);
2559
2560 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2561 return;
2562
2563 memset(&control, 0, sizeof(control));
2564 control.sframe = 1;
2565 control.super = L2CAP_SUPER_SREJ;
2566 control.reqseq = chan->srej_list.tail;
2567 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002568}
2569
2570static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2571{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002572 struct l2cap_ctrl control;
2573 u16 initial_head;
2574 u16 seq;
2575
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002576 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002577
2578 memset(&control, 0, sizeof(control));
2579 control.sframe = 1;
2580 control.super = L2CAP_SUPER_SREJ;
2581
2582 /* Capture initial list head to allow only one pass through the list. */
2583 initial_head = chan->srej_list.head;
2584
2585 do {
2586 seq = l2cap_seq_list_pop(&chan->srej_list);
2587 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2588 break;
2589
2590 control.reqseq = seq;
2591 l2cap_send_sframe(chan, &control);
2592 l2cap_seq_list_append(&chan->srej_list, seq);
2593 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002594}
2595
Mat Martineau608bcc62012-05-17 20:53:32 -07002596static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2597{
2598 struct sk_buff *acked_skb;
2599 u16 ackseq;
2600
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002601 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002602
2603 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2604 return;
2605
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002606 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002607 chan->expected_ack_seq, chan->unacked_frames);
2608
2609 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2610 ackseq = __next_seq(chan, ackseq)) {
2611
2612 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2613 if (acked_skb) {
2614 skb_unlink(acked_skb, &chan->tx_q);
2615 kfree_skb(acked_skb);
2616 chan->unacked_frames--;
2617 }
2618 }
2619
2620 chan->expected_ack_seq = reqseq;
2621
2622 if (chan->unacked_frames == 0)
2623 __clear_retrans_timer(chan);
2624
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002625 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002626}
2627
2628static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2629{
2630 BT_DBG("chan %p", chan);
2631
2632 chan->expected_tx_seq = chan->buffer_seq;
2633 l2cap_seq_list_clear(&chan->srej_list);
2634 skb_queue_purge(&chan->srej_q);
2635 chan->rx_state = L2CAP_RX_STATE_RECV;
2636}
2637
Gustavo Padovand6603662012-05-21 13:58:22 -03002638static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2639 struct l2cap_ctrl *control,
2640 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002641{
Mat Martineau608bcc62012-05-17 20:53:32 -07002642 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2643 event);
2644
2645 switch (event) {
2646 case L2CAP_EV_DATA_REQUEST:
2647 if (chan->tx_send_head == NULL)
2648 chan->tx_send_head = skb_peek(skbs);
2649
2650 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2651 l2cap_ertm_send(chan);
2652 break;
2653 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2654 BT_DBG("Enter LOCAL_BUSY");
2655 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2656
2657 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2658 /* The SREJ_SENT state must be aborted if we are to
2659 * enter the LOCAL_BUSY state.
2660 */
2661 l2cap_abort_rx_srej_sent(chan);
2662 }
2663
2664 l2cap_send_ack(chan);
2665
2666 break;
2667 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2668 BT_DBG("Exit LOCAL_BUSY");
2669 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2670
2671 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2672 struct l2cap_ctrl local_control;
2673
2674 memset(&local_control, 0, sizeof(local_control));
2675 local_control.sframe = 1;
2676 local_control.super = L2CAP_SUPER_RR;
2677 local_control.poll = 1;
2678 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002679 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002680
2681 chan->retry_count = 1;
2682 __set_monitor_timer(chan);
2683 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2684 }
2685 break;
2686 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2687 l2cap_process_reqseq(chan, control->reqseq);
2688 break;
2689 case L2CAP_EV_EXPLICIT_POLL:
2690 l2cap_send_rr_or_rnr(chan, 1);
2691 chan->retry_count = 1;
2692 __set_monitor_timer(chan);
2693 __clear_ack_timer(chan);
2694 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2695 break;
2696 case L2CAP_EV_RETRANS_TO:
2697 l2cap_send_rr_or_rnr(chan, 1);
2698 chan->retry_count = 1;
2699 __set_monitor_timer(chan);
2700 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2701 break;
2702 case L2CAP_EV_RECV_FBIT:
2703 /* Nothing to process */
2704 break;
2705 default:
2706 break;
2707 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002708}
2709
Gustavo Padovand6603662012-05-21 13:58:22 -03002710static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2711 struct l2cap_ctrl *control,
2712 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002713{
Mat Martineau608bcc62012-05-17 20:53:32 -07002714 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2715 event);
2716
2717 switch (event) {
2718 case L2CAP_EV_DATA_REQUEST:
2719 if (chan->tx_send_head == NULL)
2720 chan->tx_send_head = skb_peek(skbs);
2721 /* Queue data, but don't send. */
2722 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2723 break;
2724 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2725 BT_DBG("Enter LOCAL_BUSY");
2726 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2727
2728 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2729 /* The SREJ_SENT state must be aborted if we are to
2730 * enter the LOCAL_BUSY state.
2731 */
2732 l2cap_abort_rx_srej_sent(chan);
2733 }
2734
2735 l2cap_send_ack(chan);
2736
2737 break;
2738 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2739 BT_DBG("Exit LOCAL_BUSY");
2740 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2741
2742 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2743 struct l2cap_ctrl local_control;
2744 memset(&local_control, 0, sizeof(local_control));
2745 local_control.sframe = 1;
2746 local_control.super = L2CAP_SUPER_RR;
2747 local_control.poll = 1;
2748 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002749 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002750
2751 chan->retry_count = 1;
2752 __set_monitor_timer(chan);
2753 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2754 }
2755 break;
2756 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2757 l2cap_process_reqseq(chan, control->reqseq);
2758
2759 /* Fall through */
2760
2761 case L2CAP_EV_RECV_FBIT:
2762 if (control && control->final) {
2763 __clear_monitor_timer(chan);
2764 if (chan->unacked_frames > 0)
2765 __set_retrans_timer(chan);
2766 chan->retry_count = 0;
2767 chan->tx_state = L2CAP_TX_STATE_XMIT;
2768 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2769 }
2770 break;
2771 case L2CAP_EV_EXPLICIT_POLL:
2772 /* Ignore */
2773 break;
2774 case L2CAP_EV_MONITOR_TO:
2775 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2776 l2cap_send_rr_or_rnr(chan, 1);
2777 __set_monitor_timer(chan);
2778 chan->retry_count++;
2779 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002780 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002781 }
2782 break;
2783 default:
2784 break;
2785 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002786}
2787
Gustavo Padovand6603662012-05-21 13:58:22 -03002788static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2789 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002790{
Mat Martineau608bcc62012-05-17 20:53:32 -07002791 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2792 chan, control, skbs, event, chan->tx_state);
2793
2794 switch (chan->tx_state) {
2795 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002796 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002797 break;
2798 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002799 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002800 break;
2801 default:
2802 /* Ignore event */
2803 break;
2804 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002805}
2806
Mat Martineau4b51dae92012-05-17 20:53:37 -07002807static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2808 struct l2cap_ctrl *control)
2809{
2810 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002811 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002812}
2813
Mat Martineauf80842a2012-05-17 20:53:46 -07002814static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2815 struct l2cap_ctrl *control)
2816{
2817 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002818 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002819}
2820
Linus Torvalds1da177e2005-04-16 15:20:36 -07002821/* Copy frame to all raw sockets on that connection */
2822static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2823{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002824 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002825 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002826
2827 BT_DBG("conn %p", conn);
2828
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002829 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002830
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002831 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002832 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002833 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002834 continue;
2835
2836 /* Don't send frame to the socket it came from */
2837 if (skb->sk == sk)
2838 continue;
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002839 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002840 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002841 continue;
2842
Gustavo Padovan80b98022012-05-27 22:27:51 -03002843 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002844 kfree_skb(nskb);
2845 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002846
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002847 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002848}
2849
2850/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002851static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2852 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002853{
2854 struct sk_buff *skb, **frag;
2855 struct l2cap_cmd_hdr *cmd;
2856 struct l2cap_hdr *lh;
2857 int len, count;
2858
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002859 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2860 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002861
Anderson Lizardo300b9622013-06-02 16:30:40 -04002862 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2863 return NULL;
2864
Linus Torvalds1da177e2005-04-16 15:20:36 -07002865 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2866 count = min_t(unsigned int, conn->mtu, len);
2867
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002868 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002869 if (!skb)
2870 return NULL;
2871
2872 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002873 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002874
2875 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002876 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002877 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002878 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002879
2880 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2881 cmd->code = code;
2882 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002883 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002884
2885 if (dlen) {
2886 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2887 memcpy(skb_put(skb, count), data, count);
2888 data += count;
2889 }
2890
2891 len -= skb->len;
2892
2893 /* Continuation fragments (no L2CAP header) */
2894 frag = &skb_shinfo(skb)->frag_list;
2895 while (len) {
2896 count = min_t(unsigned int, conn->mtu, len);
2897
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002898 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002899 if (!*frag)
2900 goto fail;
2901
2902 memcpy(skb_put(*frag, count), data, count);
2903
2904 len -= count;
2905 data += count;
2906
2907 frag = &(*frag)->next;
2908 }
2909
2910 return skb;
2911
2912fail:
2913 kfree_skb(skb);
2914 return NULL;
2915}
2916
Gustavo Padovan2d792812012-10-06 10:07:01 +01002917static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2918 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002919{
2920 struct l2cap_conf_opt *opt = *ptr;
2921 int len;
2922
2923 len = L2CAP_CONF_OPT_SIZE + opt->len;
2924 *ptr += len;
2925
2926 *type = opt->type;
2927 *olen = opt->len;
2928
2929 switch (opt->len) {
2930 case 1:
2931 *val = *((u8 *) opt->val);
2932 break;
2933
2934 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002935 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002936 break;
2937
2938 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002939 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002940 break;
2941
2942 default:
2943 *val = (unsigned long) opt->val;
2944 break;
2945 }
2946
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002947 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002948 return len;
2949}
2950
Linus Torvalds1da177e2005-04-16 15:20:36 -07002951static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2952{
2953 struct l2cap_conf_opt *opt = *ptr;
2954
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002955 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002956
2957 opt->type = type;
2958 opt->len = len;
2959
2960 switch (len) {
2961 case 1:
2962 *((u8 *) opt->val) = val;
2963 break;
2964
2965 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002966 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002967 break;
2968
2969 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002970 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002971 break;
2972
2973 default:
2974 memcpy(opt->val, (void *) val, len);
2975 break;
2976 }
2977
2978 *ptr += L2CAP_CONF_OPT_SIZE + len;
2979}
2980
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002981static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2982{
2983 struct l2cap_conf_efs efs;
2984
Szymon Janc1ec918c2011-11-16 09:32:21 +01002985 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002986 case L2CAP_MODE_ERTM:
2987 efs.id = chan->local_id;
2988 efs.stype = chan->local_stype;
2989 efs.msdu = cpu_to_le16(chan->local_msdu);
2990 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002991 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002992 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002993 break;
2994
2995 case L2CAP_MODE_STREAMING:
2996 efs.id = 1;
2997 efs.stype = L2CAP_SERV_BESTEFFORT;
2998 efs.msdu = cpu_to_le16(chan->local_msdu);
2999 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
3000 efs.acc_lat = 0;
3001 efs.flush_to = 0;
3002 break;
3003
3004 default:
3005 return;
3006 }
3007
3008 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003009 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003010}
3011
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003012static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003013{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003014 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003015 ack_timer.work);
3016 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003017
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003018 BT_DBG("chan %p", chan);
3019
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003020 l2cap_chan_lock(chan);
3021
Mat Martineau03625202012-05-17 20:53:51 -07003022 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3023 chan->last_acked_seq);
3024
3025 if (frames_to_ack)
3026 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003027
3028 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003029 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003030}
3031
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003032int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003033{
Mat Martineau3c588192012-04-11 10:48:42 -07003034 int err;
3035
Mat Martineau105bdf92012-04-27 16:50:48 -07003036 chan->next_tx_seq = 0;
3037 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003038 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003039 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003040 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003041 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003042 chan->last_acked_seq = 0;
3043 chan->sdu = NULL;
3044 chan->sdu_last_frag = NULL;
3045 chan->sdu_len = 0;
3046
Mat Martineaud34c34f2012-05-14 14:49:27 -07003047 skb_queue_head_init(&chan->tx_q);
3048
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003049 chan->local_amp_id = AMP_ID_BREDR;
3050 chan->move_id = AMP_ID_BREDR;
Mat Martineau08333282012-10-23 15:24:06 -07003051 chan->move_state = L2CAP_MOVE_STABLE;
3052 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3053
Mat Martineau105bdf92012-04-27 16:50:48 -07003054 if (chan->mode != L2CAP_MODE_ERTM)
3055 return 0;
3056
3057 chan->rx_state = L2CAP_RX_STATE_RECV;
3058 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003059
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003060 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3061 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3062 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003063
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003064 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003065
Mat Martineau3c588192012-04-11 10:48:42 -07003066 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3067 if (err < 0)
3068 return err;
3069
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003070 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3071 if (err < 0)
3072 l2cap_seq_list_free(&chan->srej_list);
3073
3074 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003075}
3076
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003077static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3078{
3079 switch (mode) {
3080 case L2CAP_MODE_STREAMING:
3081 case L2CAP_MODE_ERTM:
3082 if (l2cap_mode_supported(mode, remote_feat_mask))
3083 return mode;
3084 /* fall through */
3085 default:
3086 return L2CAP_MODE_BASIC;
3087 }
3088}
3089
Marcel Holtmann848566b2013-10-01 22:59:22 -07003090static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003091{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003092 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003093}
3094
Marcel Holtmann848566b2013-10-01 22:59:22 -07003095static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003096{
Marcel Holtmann848566b2013-10-01 22:59:22 -07003097 return conn->hs_enabled && conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003098}
3099
Mat Martineau36c86c82012-10-23 15:24:20 -07003100static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3101 struct l2cap_conf_rfc *rfc)
3102{
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003103 if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) {
Mat Martineau36c86c82012-10-23 15:24:20 -07003104 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3105
3106 /* Class 1 devices have must have ERTM timeouts
3107 * exceeding the Link Supervision Timeout. The
3108 * default Link Supervision Timeout for AMP
3109 * controllers is 10 seconds.
3110 *
3111 * Class 1 devices use 0xffffffff for their
3112 * best-effort flush timeout, so the clamping logic
3113 * will result in a timeout that meets the above
3114 * requirement. ERTM timeouts are 16-bit values, so
3115 * the maximum timeout is 65.535 seconds.
3116 */
3117
3118 /* Convert timeout to milliseconds and round */
3119 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3120
3121 /* This is the recommended formula for class 2 devices
3122 * that start ERTM timers when packets are sent to the
3123 * controller.
3124 */
3125 ertm_to = 3 * ertm_to + 500;
3126
3127 if (ertm_to > 0xffff)
3128 ertm_to = 0xffff;
3129
3130 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3131 rfc->monitor_timeout = rfc->retrans_timeout;
3132 } else {
3133 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3134 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3135 }
3136}
3137
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003138static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3139{
3140 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Marcel Holtmann848566b2013-10-01 22:59:22 -07003141 __l2cap_ews_supported(chan->conn)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003142 /* use extended control field */
3143 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003144 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3145 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003146 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003147 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003148 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3149 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003150 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003151}
3152
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003153static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003154{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003155 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003156 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003157 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003158 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003159
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003160 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003161
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003162 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003163 goto done;
3164
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003165 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003166 case L2CAP_MODE_STREAMING:
3167 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003168 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003169 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003170
Marcel Holtmann848566b2013-10-01 22:59:22 -07003171 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003172 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3173
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003174 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003175 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003176 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003177 break;
3178 }
3179
3180done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003181 if (chan->imtu != L2CAP_DEFAULT_MTU)
3182 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003183
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003184 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003185 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003186 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003187 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003188 break;
3189
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003190 rfc.mode = L2CAP_MODE_BASIC;
3191 rfc.txwin_size = 0;
3192 rfc.max_transmit = 0;
3193 rfc.retrans_timeout = 0;
3194 rfc.monitor_timeout = 0;
3195 rfc.max_pdu_size = 0;
3196
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003197 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003198 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003199 break;
3200
3201 case L2CAP_MODE_ERTM:
3202 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003203 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003204
3205 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003206
3207 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003208 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3209 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003210 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003211
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003212 l2cap_txwin_setup(chan);
3213
3214 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003215 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003216
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003217 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003218 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003219
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003220 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3221 l2cap_add_opt_efs(&ptr, chan);
3222
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003223 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3224 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003225 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003226
3227 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3228 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003229 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003230 chan->fcs = L2CAP_FCS_NONE;
3231 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3232 chan->fcs);
3233 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003234 break;
3235
3236 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003237 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003238 rfc.mode = L2CAP_MODE_STREAMING;
3239 rfc.txwin_size = 0;
3240 rfc.max_transmit = 0;
3241 rfc.retrans_timeout = 0;
3242 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003243
3244 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003245 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3246 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003247 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003248
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003249 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003250 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003251
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003252 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3253 l2cap_add_opt_efs(&ptr, chan);
3254
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003255 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3256 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003257 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003258 chan->fcs = L2CAP_FCS_NONE;
3259 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3260 chan->fcs);
3261 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003262 break;
3263 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003264
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003265 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003266 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003267
3268 return ptr - data;
3269}
3270
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003271static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003272{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003273 struct l2cap_conf_rsp *rsp = data;
3274 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003275 void *req = chan->conf_req;
3276 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003277 int type, hint, olen;
3278 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003279 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003280 struct l2cap_conf_efs efs;
3281 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003282 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003283 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003284 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003285
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003286 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003287
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003288 while (len >= L2CAP_CONF_OPT_SIZE) {
3289 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003290
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003291 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003292 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003293
3294 switch (type) {
3295 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003296 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003297 break;
3298
3299 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003300 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003301 break;
3302
3303 case L2CAP_CONF_QOS:
3304 break;
3305
Marcel Holtmann6464f352007-10-20 13:39:51 +02003306 case L2CAP_CONF_RFC:
3307 if (olen == sizeof(rfc))
3308 memcpy(&rfc, (void *) val, olen);
3309 break;
3310
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003311 case L2CAP_CONF_FCS:
3312 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003313 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003314 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003315
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003316 case L2CAP_CONF_EFS:
3317 remote_efs = 1;
3318 if (olen == sizeof(efs))
3319 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003320 break;
3321
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003322 case L2CAP_CONF_EWS:
Marcel Holtmann848566b2013-10-01 22:59:22 -07003323 if (!chan->conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003324 return -ECONNREFUSED;
3325
3326 set_bit(FLAG_EXT_CTRL, &chan->flags);
3327 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003328 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003329 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003330 break;
3331
3332 default:
3333 if (hint)
3334 break;
3335
3336 result = L2CAP_CONF_UNKNOWN;
3337 *((u8 *) ptr++) = type;
3338 break;
3339 }
3340 }
3341
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003342 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003343 goto done;
3344
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003345 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003346 case L2CAP_MODE_STREAMING:
3347 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003348 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003349 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003350 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003351 break;
3352 }
3353
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003354 if (remote_efs) {
Marcel Holtmann848566b2013-10-01 22:59:22 -07003355 if (__l2cap_efs_supported(chan->conn))
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003356 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3357 else
3358 return -ECONNREFUSED;
3359 }
3360
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003361 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003362 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003363
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003364 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003365 }
3366
3367done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003368 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003369 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003370 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003371
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003372 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003373 return -ECONNREFUSED;
3374
Gustavo Padovan2d792812012-10-06 10:07:01 +01003375 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3376 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003377 }
3378
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003379 if (result == L2CAP_CONF_SUCCESS) {
3380 /* Configure output options and let the other side know
3381 * which ones we don't like. */
3382
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003383 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3384 result = L2CAP_CONF_UNACCEPT;
3385 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003386 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003387 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003388 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003389 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003390
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003391 if (remote_efs) {
3392 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003393 efs.stype != L2CAP_SERV_NOTRAFIC &&
3394 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003395
3396 result = L2CAP_CONF_UNACCEPT;
3397
3398 if (chan->num_conf_req >= 1)
3399 return -ECONNREFUSED;
3400
3401 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003402 sizeof(efs),
3403 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003404 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003405 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003406 result = L2CAP_CONF_PENDING;
3407 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003408 }
3409 }
3410
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003411 switch (rfc.mode) {
3412 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003413 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003414 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003415 break;
3416
3417 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003418 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3419 chan->remote_tx_win = rfc.txwin_size;
3420 else
3421 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3422
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003423 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003424
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003425 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003426 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3427 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003428 rfc.max_pdu_size = cpu_to_le16(size);
3429 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003430
Mat Martineau36c86c82012-10-23 15:24:20 -07003431 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003432
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003433 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003434
3435 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003436 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003437
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003438 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3439 chan->remote_id = efs.id;
3440 chan->remote_stype = efs.stype;
3441 chan->remote_msdu = le16_to_cpu(efs.msdu);
3442 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003443 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003444 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003445 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003446 chan->remote_sdu_itime =
3447 le32_to_cpu(efs.sdu_itime);
3448 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003449 sizeof(efs),
3450 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003451 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003452 break;
3453
3454 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003455 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003456 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3457 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003458 rfc.max_pdu_size = cpu_to_le16(size);
3459 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003460
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003461 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003462
Gustavo Padovan2d792812012-10-06 10:07:01 +01003463 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3464 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003465
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003466 break;
3467
3468 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003469 result = L2CAP_CONF_UNACCEPT;
3470
3471 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003472 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003473 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003474
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003475 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003476 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003477 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003478 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003479 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003480 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003481
3482 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003483}
3484
Gustavo Padovan2d792812012-10-06 10:07:01 +01003485static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3486 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003487{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003488 struct l2cap_conf_req *req = data;
3489 void *ptr = req->data;
3490 int type, olen;
3491 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003492 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003493 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003494
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003495 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003496
3497 while (len >= L2CAP_CONF_OPT_SIZE) {
3498 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3499
3500 switch (type) {
3501 case L2CAP_CONF_MTU:
3502 if (val < L2CAP_DEFAULT_MIN_MTU) {
3503 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003504 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003505 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003506 chan->imtu = val;
3507 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003508 break;
3509
3510 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003511 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003512 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003513 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003514 break;
3515
3516 case L2CAP_CONF_RFC:
3517 if (olen == sizeof(rfc))
3518 memcpy(&rfc, (void *)val, olen);
3519
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003520 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003521 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003522 return -ECONNREFUSED;
3523
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003524 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003525
3526 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003527 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003528 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003529
3530 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003531 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003532 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003533 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003534 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003535
3536 case L2CAP_CONF_EFS:
3537 if (olen == sizeof(efs))
3538 memcpy(&efs, (void *)val, olen);
3539
3540 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003541 efs.stype != L2CAP_SERV_NOTRAFIC &&
3542 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003543 return -ECONNREFUSED;
3544
Gustavo Padovan2d792812012-10-06 10:07:01 +01003545 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3546 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003547 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003548
3549 case L2CAP_CONF_FCS:
3550 if (*result == L2CAP_CONF_PENDING)
3551 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003552 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003553 &chan->conf_state);
3554 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003555 }
3556 }
3557
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003558 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003559 return -ECONNREFUSED;
3560
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003561 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003562
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003563 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003564 switch (rfc.mode) {
3565 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003566 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3567 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3568 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003569 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3570 chan->ack_win = min_t(u16, chan->ack_win,
3571 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003572
3573 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3574 chan->local_msdu = le16_to_cpu(efs.msdu);
3575 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003576 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003577 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3578 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003579 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003580 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003581 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003582
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003583 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003584 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003585 }
3586 }
3587
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003588 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003589 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003590
3591 return ptr - data;
3592}
3593
Gustavo Padovan2d792812012-10-06 10:07:01 +01003594static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3595 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003596{
3597 struct l2cap_conf_rsp *rsp = data;
3598 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003599
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003600 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003601
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003602 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003603 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003604 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003605
3606 return ptr - data;
3607}
3608
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003609void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003610{
3611 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003612 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003613 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003614 u8 rsp_code;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003615
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003616 rsp.scid = cpu_to_le16(chan->dcid);
3617 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003618 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3619 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003620
3621 if (chan->hs_hcon)
3622 rsp_code = L2CAP_CREATE_CHAN_RSP;
3623 else
3624 rsp_code = L2CAP_CONN_RSP;
3625
3626 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3627
3628 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003629
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003630 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003631 return;
3632
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003633 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003634 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003635 chan->num_conf_req++;
3636}
3637
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003638static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003639{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003640 int type, olen;
3641 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003642 /* Use sane default values in case a misbehaving remote device
3643 * did not send an RFC or extended window size option.
3644 */
3645 u16 txwin_ext = chan->ack_win;
3646 struct l2cap_conf_rfc rfc = {
3647 .mode = chan->mode,
3648 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3649 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3650 .max_pdu_size = cpu_to_le16(chan->imtu),
3651 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3652 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003653
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003654 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003655
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003656 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003657 return;
3658
3659 while (len >= L2CAP_CONF_OPT_SIZE) {
3660 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3661
Mat Martineauc20f8e32012-07-10 05:47:07 -07003662 switch (type) {
3663 case L2CAP_CONF_RFC:
3664 if (olen == sizeof(rfc))
3665 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003666 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003667 case L2CAP_CONF_EWS:
3668 txwin_ext = val;
3669 break;
3670 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003671 }
3672
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003673 switch (rfc.mode) {
3674 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003675 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3676 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003677 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3678 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3679 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3680 else
3681 chan->ack_win = min_t(u16, chan->ack_win,
3682 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003683 break;
3684 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003685 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003686 }
3687}
3688
Gustavo Padovan2d792812012-10-06 10:07:01 +01003689static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003690 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3691 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003692{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003693 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003694
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003695 if (cmd_len < sizeof(*rej))
3696 return -EPROTO;
3697
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003698 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003699 return 0;
3700
3701 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003702 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003703 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003704
3705 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003706 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003707
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003708 l2cap_conn_start(conn);
3709 }
3710
3711 return 0;
3712}
3713
Mat Martineau17009152012-10-23 15:24:07 -07003714static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3715 struct l2cap_cmd_hdr *cmd,
3716 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003717{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003718 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3719 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003720 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003721 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003722 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003723
3724 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003725 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003726
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003727 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003728
3729 /* Check if we have socket listening on psm */
Marcel Holtmann6f59b902013-10-13 05:24:01 -07003730 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07003731 &conn->hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003732 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003733 result = L2CAP_CR_BAD_PSM;
3734 goto sendresp;
3735 }
3736
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003737 parent = pchan->sk;
3738
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003739 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003740 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003741
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003742 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003743 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003744 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003745 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003746 result = L2CAP_CR_SEC_BLOCK;
3747 goto response;
3748 }
3749
Linus Torvalds1da177e2005-04-16 15:20:36 -07003750 result = L2CAP_CR_NO_MEM;
3751
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003752 /* Check if we already have channel with that dcid */
3753 if (__l2cap_get_chan_by_dcid(conn, scid))
3754 goto response;
3755
Gustavo Padovan80b98022012-05-27 22:27:51 -03003756 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003757 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003758 goto response;
3759
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003760 sk = chan->sk;
3761
Syam Sidhardhan330b6c12013-08-06 01:59:12 +09003762 /* For certain devices (ex: HID mouse), support for authentication,
3763 * pairing and bonding is optional. For such devices, inorder to avoid
3764 * the ACL alive for too long after L2CAP disconnection, reset the ACL
3765 * disc_timeout back to HCI_DISCONN_TIMEOUT during L2CAP connect.
3766 */
3767 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
3768
Marcel Holtmann7eafc592013-10-13 08:12:47 -07003769 bacpy(&chan->src, &conn->hcon->src);
3770 bacpy(&chan->dst, &conn->hcon->dst);
Marcel Holtmann4f1654e2013-10-13 08:50:41 -07003771 chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
3772 chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003773 chan->psm = psm;
3774 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003775 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003776
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003777 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003778
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003779 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003780
Gustavo Padovan8d836d72013-10-15 19:24:47 -03003781 __set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003782
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003783 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003784
Marcel Holtmann984947d2009-02-06 23:35:19 +01003785 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003786 if (l2cap_chan_check_security(chan)) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07003787 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003788 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003789 result = L2CAP_CR_PEND;
3790 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003791 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003792 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003793 /* Force pending result for AMP controllers.
3794 * The connection will succeed after the
3795 * physical link is up.
3796 */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003797 if (amp_id == AMP_ID_BREDR) {
Mat Martineau17009152012-10-23 15:24:07 -07003798 __l2cap_state_change(chan, BT_CONFIG);
3799 result = L2CAP_CR_SUCCESS;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07003800 } else {
3801 __l2cap_state_change(chan, BT_CONNECT2);
3802 result = L2CAP_CR_PEND;
Mat Martineau17009152012-10-23 15:24:07 -07003803 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003804 status = L2CAP_CS_NO_INFO;
3805 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003806 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003807 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003808 result = L2CAP_CR_PEND;
3809 status = L2CAP_CS_AUTHEN_PEND;
3810 }
3811 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003812 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003813 result = L2CAP_CR_PEND;
3814 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003815 }
3816
Linus Torvalds1da177e2005-04-16 15:20:36 -07003817response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003818 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003819 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003820
3821sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003822 rsp.scid = cpu_to_le16(scid);
3823 rsp.dcid = cpu_to_le16(dcid);
3824 rsp.result = cpu_to_le16(result);
3825 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003826 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003827
3828 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3829 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003830 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003831
3832 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3833 conn->info_ident = l2cap_get_ident(conn);
3834
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003835 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003836
Gustavo Padovan2d792812012-10-06 10:07:01 +01003837 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3838 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003839 }
3840
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003841 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003842 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003843 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003844 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003845 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003846 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003847 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003848 }
Mat Martineau17009152012-10-23 15:24:07 -07003849
3850 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003851}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003852
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003853static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003854 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003855{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303856 struct hci_dev *hdev = conn->hcon->hdev;
3857 struct hci_conn *hcon = conn->hcon;
3858
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003859 if (cmd_len < sizeof(struct l2cap_conn_req))
3860 return -EPROTO;
3861
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303862 hci_dev_lock(hdev);
3863 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3864 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3865 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3866 hcon->dst_type, 0, NULL, 0,
3867 hcon->dev_class);
3868 hci_dev_unlock(hdev);
3869
Gustavo Padovan300229f2012-10-12 19:40:40 +08003870 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003871 return 0;
3872}
3873
Mat Martineau5909cf32012-10-23 15:24:08 -07003874static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003875 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3876 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003877{
3878 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3879 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003880 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003881 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003882 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003883
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003884 if (cmd_len < sizeof(*rsp))
3885 return -EPROTO;
3886
Linus Torvalds1da177e2005-04-16 15:20:36 -07003887 scid = __le16_to_cpu(rsp->scid);
3888 dcid = __le16_to_cpu(rsp->dcid);
3889 result = __le16_to_cpu(rsp->result);
3890 status = __le16_to_cpu(rsp->status);
3891
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003892 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 +01003893 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003894
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003895 mutex_lock(&conn->chan_lock);
3896
Linus Torvalds1da177e2005-04-16 15:20:36 -07003897 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003898 chan = __l2cap_get_chan_by_scid(conn, scid);
3899 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003900 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003901 goto unlock;
3902 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003903 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003904 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3905 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003906 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003907 goto unlock;
3908 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003909 }
3910
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003911 err = 0;
3912
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003913 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003914
Linus Torvalds1da177e2005-04-16 15:20:36 -07003915 switch (result) {
3916 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003917 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003918 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003919 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003920 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003921
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003922 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003923 break;
3924
Linus Torvalds1da177e2005-04-16 15:20:36 -07003925 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003926 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003927 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003928 break;
3929
3930 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003931 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003932 break;
3933
3934 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003935 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003936 break;
3937 }
3938
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003939 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003940
3941unlock:
3942 mutex_unlock(&conn->chan_lock);
3943
3944 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003945}
3946
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003947static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003948{
3949 /* FCS is enabled only in ERTM or streaming mode, if one or both
3950 * sides request it.
3951 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003952 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003953 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003954 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003955 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003956}
3957
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003958static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3959 u8 ident, u16 flags)
3960{
3961 struct l2cap_conn *conn = chan->conn;
3962
3963 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3964 flags);
3965
3966 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3967 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3968
3969 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
3970 l2cap_build_conf_rsp(chan, data,
3971 L2CAP_CONF_SUCCESS, flags), data);
3972}
3973
Gustavo Padovan2d792812012-10-06 10:07:01 +01003974static inline int l2cap_config_req(struct l2cap_conn *conn,
3975 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3976 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003977{
3978 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3979 u16 dcid, flags;
3980 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003981 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003982 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003983
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003984 if (cmd_len < sizeof(*req))
3985 return -EPROTO;
3986
Linus Torvalds1da177e2005-04-16 15:20:36 -07003987 dcid = __le16_to_cpu(req->dcid);
3988 flags = __le16_to_cpu(req->flags);
3989
3990 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3991
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003992 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003993 if (!chan)
Johan Hedberg21870b52013-09-16 13:05:14 +03003994 return -EBADSLT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003995
David S. Miller033b1142011-07-21 13:38:42 -07003996 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003997 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003998
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003999 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004000 rej.scid = cpu_to_le16(chan->scid);
4001 rej.dcid = cpu_to_le16(chan->dcid);
4002
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004003 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004004 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004005 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004006 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004007
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004008 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07004009 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004010 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004011 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004012 l2cap_build_conf_rsp(chan, rsp,
4013 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004014 goto unlock;
4015 }
4016
4017 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004018 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4019 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004020
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004021 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004022 /* Incomplete config. Send empty response. */
4023 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004024 l2cap_build_conf_rsp(chan, rsp,
4025 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004026 goto unlock;
4027 }
4028
4029 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004030 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004031 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004032 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004033 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004034 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004035
Mat Martineau1500109b2012-10-23 15:24:15 -07004036 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004037 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004038 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004039
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004040 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004041 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004042
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004043 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004044 goto unlock;
4045
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004046 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004047 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004048
Mat Martineau105bdf92012-04-27 16:50:48 -07004049 if (chan->mode == L2CAP_MODE_ERTM ||
4050 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004051 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004052
Mat Martineau3c588192012-04-11 10:48:42 -07004053 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004054 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004055 else
4056 l2cap_chan_ready(chan);
4057
Marcel Holtmann876d9482007-10-20 13:35:42 +02004058 goto unlock;
4059 }
4060
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004061 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004062 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004063 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004064 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004065 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004066 }
4067
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004068 /* Got Conf Rsp PENDING from remote side and asume we sent
4069 Conf Rsp PENDING in the code above */
4070 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004071 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004072
4073 /* check compatibility */
4074
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004075 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004076 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004077 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4078 else
4079 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004080 }
4081
Linus Torvalds1da177e2005-04-16 15:20:36 -07004082unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004083 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004084 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004085}
4086
Gustavo Padovan2d792812012-10-06 10:07:01 +01004087static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004088 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4089 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004090{
4091 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4092 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004093 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004094 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004095 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004096
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004097 if (cmd_len < sizeof(*rsp))
4098 return -EPROTO;
4099
Linus Torvalds1da177e2005-04-16 15:20:36 -07004100 scid = __le16_to_cpu(rsp->scid);
4101 flags = __le16_to_cpu(rsp->flags);
4102 result = __le16_to_cpu(rsp->result);
4103
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004104 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4105 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004106
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004107 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004108 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004109 return 0;
4110
4111 switch (result) {
4112 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004113 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004114 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004115 break;
4116
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004117 case L2CAP_CONF_PENDING:
4118 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4119
4120 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4121 char buf[64];
4122
4123 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004124 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004125 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004126 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004127 goto done;
4128 }
4129
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004130 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004131 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4132 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004133 } else {
4134 if (l2cap_check_efs(chan)) {
4135 amp_create_logical_link(chan);
4136 chan->ident = cmd->ident;
4137 }
4138 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004139 }
4140 goto done;
4141
Linus Torvalds1da177e2005-04-16 15:20:36 -07004142 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004143 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004144 char req[64];
4145
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004146 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004147 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004148 goto done;
4149 }
4150
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004151 /* throw out any old stored conf requests */
4152 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004153 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004154 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004155 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004156 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004157 goto done;
4158 }
4159
4160 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004161 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004162 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004163 if (result != L2CAP_CONF_SUCCESS)
4164 goto done;
4165 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004166 }
4167
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004168 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004169 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004170
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004171 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004172 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004173 goto done;
4174 }
4175
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004176 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004177 goto done;
4178
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004179 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004180
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004181 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004182 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004183
Mat Martineau105bdf92012-04-27 16:50:48 -07004184 if (chan->mode == L2CAP_MODE_ERTM ||
4185 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004186 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004187
Mat Martineau3c588192012-04-11 10:48:42 -07004188 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004189 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004190 else
4191 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004192 }
4193
4194done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004195 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004196 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004197}
4198
Gustavo Padovan2d792812012-10-06 10:07:01 +01004199static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004200 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4201 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004202{
4203 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4204 struct l2cap_disconn_rsp rsp;
4205 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004206 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004207
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004208 if (cmd_len != sizeof(*req))
4209 return -EPROTO;
4210
Linus Torvalds1da177e2005-04-16 15:20:36 -07004211 scid = __le16_to_cpu(req->scid);
4212 dcid = __le16_to_cpu(req->dcid);
4213
4214 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4215
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004216 mutex_lock(&conn->chan_lock);
4217
4218 chan = __l2cap_get_chan_by_scid(conn, dcid);
4219 if (!chan) {
4220 mutex_unlock(&conn->chan_lock);
Johan Hedbergc4ea2492013-09-16 13:05:15 +03004221 return -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004222 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004223
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004224 l2cap_chan_lock(chan);
4225
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004226 rsp.dcid = cpu_to_le16(chan->scid);
4227 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004228 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4229
Gustavo Padovan5ec1bbe2013-10-15 19:24:48 -03004230 chan->ops->set_shutdown(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004231
Mat Martineau61d6ef32012-04-27 16:50:50 -07004232 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004233 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004234
4235 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004236
Gustavo Padovan80b98022012-05-27 22:27:51 -03004237 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004238 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004239
4240 mutex_unlock(&conn->chan_lock);
4241
Linus Torvalds1da177e2005-04-16 15:20:36 -07004242 return 0;
4243}
4244
Gustavo Padovan2d792812012-10-06 10:07:01 +01004245static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004246 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4247 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004248{
4249 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4250 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004251 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004252
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004253 if (cmd_len != sizeof(*rsp))
4254 return -EPROTO;
4255
Linus Torvalds1da177e2005-04-16 15:20:36 -07004256 scid = __le16_to_cpu(rsp->scid);
4257 dcid = __le16_to_cpu(rsp->dcid);
4258
4259 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4260
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004261 mutex_lock(&conn->chan_lock);
4262
4263 chan = __l2cap_get_chan_by_scid(conn, scid);
4264 if (!chan) {
4265 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004266 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004267 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004268
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004269 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004270
Mat Martineau61d6ef32012-04-27 16:50:50 -07004271 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004272 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004273
4274 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004275
Gustavo Padovan80b98022012-05-27 22:27:51 -03004276 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004277 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004278
4279 mutex_unlock(&conn->chan_lock);
4280
Linus Torvalds1da177e2005-04-16 15:20:36 -07004281 return 0;
4282}
4283
Gustavo Padovan2d792812012-10-06 10:07:01 +01004284static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004285 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4286 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004287{
4288 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004289 u16 type;
4290
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004291 if (cmd_len != sizeof(*req))
4292 return -EPROTO;
4293
Linus Torvalds1da177e2005-04-16 15:20:36 -07004294 type = __le16_to_cpu(req->type);
4295
4296 BT_DBG("type 0x%4.4x", type);
4297
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004298 if (type == L2CAP_IT_FEAT_MASK) {
4299 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004300 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004301 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004302 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4303 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004304 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004305 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004306 | L2CAP_FEAT_FCS;
Marcel Holtmann848566b2013-10-01 22:59:22 -07004307 if (conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004308 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004309 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004310
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004311 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004312 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4313 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004314 } else if (type == L2CAP_IT_FIXED_CHAN) {
4315 u8 buf[12];
4316 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004317
Marcel Holtmann848566b2013-10-01 22:59:22 -07004318 if (conn->hs_enabled)
Mat Martineau50a147c2011-11-02 16:18:34 -07004319 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4320 else
4321 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4322
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004323 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4324 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004325 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004326 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4327 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004328 } else {
4329 struct l2cap_info_rsp rsp;
4330 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004331 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004332 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4333 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004334 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004335
4336 return 0;
4337}
4338
Gustavo Padovan2d792812012-10-06 10:07:01 +01004339static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004340 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4341 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004342{
4343 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4344 u16 type, result;
4345
Jaganath Kanakkassery3f6fa3d2013-06-21 19:55:11 +05304346 if (cmd_len < sizeof(*rsp))
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004347 return -EPROTO;
4348
Linus Torvalds1da177e2005-04-16 15:20:36 -07004349 type = __le16_to_cpu(rsp->type);
4350 result = __le16_to_cpu(rsp->result);
4351
4352 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4353
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004354 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4355 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004356 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004357 return 0;
4358
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004359 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004360
Ville Tervoadb08ed2010-08-04 09:43:33 +03004361 if (result != L2CAP_IR_SUCCESS) {
4362 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4363 conn->info_ident = 0;
4364
4365 l2cap_conn_start(conn);
4366
4367 return 0;
4368 }
4369
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004370 switch (type) {
4371 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004372 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004373
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004374 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004375 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004376 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004377
4378 conn->info_ident = l2cap_get_ident(conn);
4379
4380 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004381 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004382 } else {
4383 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4384 conn->info_ident = 0;
4385
4386 l2cap_conn_start(conn);
4387 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004388 break;
4389
4390 case L2CAP_IT_FIXED_CHAN:
4391 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004392 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004393 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004394
4395 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004396 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004397 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004398
Linus Torvalds1da177e2005-04-16 15:20:36 -07004399 return 0;
4400}
4401
Mat Martineau17009152012-10-23 15:24:07 -07004402static int l2cap_create_channel_req(struct l2cap_conn *conn,
4403 struct l2cap_cmd_hdr *cmd,
4404 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004405{
4406 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004407 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004408 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004409 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004410 u16 psm, scid;
4411
4412 if (cmd_len != sizeof(*req))
4413 return -EPROTO;
4414
Marcel Holtmann848566b2013-10-01 22:59:22 -07004415 if (!conn->hs_enabled)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004416 return -EINVAL;
4417
4418 psm = le16_to_cpu(req->psm);
4419 scid = le16_to_cpu(req->scid);
4420
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004421 BT_DBG("psm 0x%2.2x, scid 0x%4.4x, amp_id %d", psm, scid, req->amp_id);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004422
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004423 /* For controller id 0 make BR/EDR connection */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004424 if (req->amp_id == AMP_ID_BREDR) {
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004425 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4426 req->amp_id);
4427 return 0;
4428 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004429
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004430 /* Validate AMP controller id */
4431 hdev = hci_dev_get(req->amp_id);
4432 if (!hdev)
4433 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004434
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004435 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004436 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004437 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004438 }
4439
4440 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4441 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004442 if (chan) {
4443 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4444 struct hci_conn *hs_hcon;
4445
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07004446 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
4447 &conn->hcon->dst);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004448 if (!hs_hcon) {
4449 hci_dev_put(hdev);
Johan Hedberg21870b52013-09-16 13:05:14 +03004450 return -EBADSLT;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004451 }
4452
4453 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4454
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004455 mgr->bredr_chan = chan;
4456 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004457 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004458 conn->mtu = hdev->block_mtu;
4459 }
4460
4461 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004462
4463 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004464
4465error:
4466 rsp.dcid = 0;
4467 rsp.scid = cpu_to_le16(scid);
4468 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4469 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4470
4471 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4472 sizeof(rsp), &rsp);
4473
Johan Hedbergdc280802013-09-16 13:05:13 +03004474 return 0;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004475}
4476
Mat Martineau8eb200b2012-10-23 15:24:17 -07004477static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4478{
4479 struct l2cap_move_chan_req req;
4480 u8 ident;
4481
4482 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4483
4484 ident = l2cap_get_ident(chan->conn);
4485 chan->ident = ident;
4486
4487 req.icid = cpu_to_le16(chan->scid);
4488 req.dest_amp_id = dest_amp_id;
4489
4490 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4491 &req);
4492
4493 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4494}
4495
Mat Martineau1500109b2012-10-23 15:24:15 -07004496static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004497{
4498 struct l2cap_move_chan_rsp rsp;
4499
Mat Martineau1500109b2012-10-23 15:24:15 -07004500 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004501
Mat Martineau1500109b2012-10-23 15:24:15 -07004502 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004503 rsp.result = cpu_to_le16(result);
4504
Mat Martineau1500109b2012-10-23 15:24:15 -07004505 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4506 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004507}
4508
Mat Martineau5b155ef2012-10-23 15:24:14 -07004509static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004510{
4511 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004512
Mat Martineau5b155ef2012-10-23 15:24:14 -07004513 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004514
Mat Martineau5b155ef2012-10-23 15:24:14 -07004515 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004516
Mat Martineau5b155ef2012-10-23 15:24:14 -07004517 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004518 cfm.result = cpu_to_le16(result);
4519
Mat Martineau5b155ef2012-10-23 15:24:14 -07004520 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4521 sizeof(cfm), &cfm);
4522
4523 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4524}
4525
4526static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4527{
4528 struct l2cap_move_chan_cfm cfm;
4529
4530 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4531
4532 cfm.icid = cpu_to_le16(icid);
4533 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4534
4535 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4536 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004537}
4538
4539static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004540 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004541{
4542 struct l2cap_move_chan_cfm_rsp rsp;
4543
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004544 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004545
4546 rsp.icid = cpu_to_le16(icid);
4547 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4548}
4549
Mat Martineau5f3847a2012-10-23 15:24:12 -07004550static void __release_logical_link(struct l2cap_chan *chan)
4551{
4552 chan->hs_hchan = NULL;
4553 chan->hs_hcon = NULL;
4554
4555 /* Placeholder - release the logical link */
4556}
4557
Mat Martineau1500109b2012-10-23 15:24:15 -07004558static void l2cap_logical_fail(struct l2cap_chan *chan)
4559{
4560 /* Logical link setup failed */
4561 if (chan->state != BT_CONNECTED) {
4562 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004563 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004564 return;
4565 }
4566
4567 switch (chan->move_role) {
4568 case L2CAP_MOVE_ROLE_RESPONDER:
4569 l2cap_move_done(chan);
4570 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4571 break;
4572 case L2CAP_MOVE_ROLE_INITIATOR:
4573 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4574 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4575 /* Remote has only sent pending or
4576 * success responses, clean up
4577 */
4578 l2cap_move_done(chan);
4579 }
4580
4581 /* Other amp move states imply that the move
4582 * has already aborted
4583 */
4584 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4585 break;
4586 }
4587}
4588
4589static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4590 struct hci_chan *hchan)
4591{
4592 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004593
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004594 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004595 chan->hs_hcon->l2cap_data = chan->conn;
4596
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004597 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004598
4599 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004600 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004601
4602 set_default_fcs(chan);
4603
4604 err = l2cap_ertm_init(chan);
4605 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004606 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004607 else
4608 l2cap_chan_ready(chan);
4609 }
4610}
4611
4612static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4613 struct hci_chan *hchan)
4614{
4615 chan->hs_hcon = hchan->conn;
4616 chan->hs_hcon->l2cap_data = chan->conn;
4617
4618 BT_DBG("move_state %d", chan->move_state);
4619
4620 switch (chan->move_state) {
4621 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4622 /* Move confirm will be sent after a success
4623 * response is received
4624 */
4625 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4626 break;
4627 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4628 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4629 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4630 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4631 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4632 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4633 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4634 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4635 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4636 }
4637 break;
4638 default:
4639 /* Move was not in expected state, free the channel */
4640 __release_logical_link(chan);
4641
4642 chan->move_state = L2CAP_MOVE_STABLE;
4643 }
4644}
4645
4646/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004647void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4648 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004649{
Mat Martineau1500109b2012-10-23 15:24:15 -07004650 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4651
4652 if (status) {
4653 l2cap_logical_fail(chan);
4654 __release_logical_link(chan);
4655 return;
4656 }
4657
4658 if (chan->state != BT_CONNECTED) {
4659 /* Ignore logical link if channel is on BR/EDR */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004660 if (chan->local_amp_id != AMP_ID_BREDR)
Mat Martineau1500109b2012-10-23 15:24:15 -07004661 l2cap_logical_finish_create(chan, hchan);
4662 } else {
4663 l2cap_logical_finish_move(chan, hchan);
4664 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004665}
4666
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004667void l2cap_move_start(struct l2cap_chan *chan)
4668{
4669 BT_DBG("chan %p", chan);
4670
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004671 if (chan->local_amp_id == AMP_ID_BREDR) {
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004672 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4673 return;
4674 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4675 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4676 /* Placeholder - start physical link setup */
4677 } else {
4678 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4679 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4680 chan->move_id = 0;
4681 l2cap_move_setup(chan);
4682 l2cap_send_move_chan_req(chan, 0);
4683 }
4684}
4685
Mat Martineau8eb200b2012-10-23 15:24:17 -07004686static void l2cap_do_create(struct l2cap_chan *chan, int result,
4687 u8 local_amp_id, u8 remote_amp_id)
4688{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004689 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4690 local_amp_id, remote_amp_id);
4691
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004692 chan->fcs = L2CAP_FCS_NONE;
4693
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004694 /* Outgoing channel on AMP */
4695 if (chan->state == BT_CONNECT) {
4696 if (result == L2CAP_CR_SUCCESS) {
4697 chan->local_amp_id = local_amp_id;
4698 l2cap_send_create_chan_req(chan, remote_amp_id);
4699 } else {
4700 /* Revert to BR/EDR connect */
4701 l2cap_send_conn_req(chan);
4702 }
4703
4704 return;
4705 }
4706
4707 /* Incoming channel on AMP */
4708 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004709 struct l2cap_conn_rsp rsp;
4710 char buf[128];
4711 rsp.scid = cpu_to_le16(chan->dcid);
4712 rsp.dcid = cpu_to_le16(chan->scid);
4713
Mat Martineau8eb200b2012-10-23 15:24:17 -07004714 if (result == L2CAP_CR_SUCCESS) {
4715 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004716 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4717 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004718 } else {
4719 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004720 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4721 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004722 }
4723
4724 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4725 sizeof(rsp), &rsp);
4726
4727 if (result == L2CAP_CR_SUCCESS) {
4728 __l2cap_state_change(chan, BT_CONFIG);
4729 set_bit(CONF_REQ_SENT, &chan->conf_state);
4730 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4731 L2CAP_CONF_REQ,
4732 l2cap_build_conf_req(chan, buf), buf);
4733 chan->num_conf_req++;
4734 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004735 }
4736}
4737
4738static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4739 u8 remote_amp_id)
4740{
4741 l2cap_move_setup(chan);
4742 chan->move_id = local_amp_id;
4743 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4744
4745 l2cap_send_move_chan_req(chan, remote_amp_id);
4746}
4747
4748static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4749{
4750 struct hci_chan *hchan = NULL;
4751
4752 /* Placeholder - get hci_chan for logical link */
4753
4754 if (hchan) {
4755 if (hchan->state == BT_CONNECTED) {
4756 /* Logical link is ready to go */
4757 chan->hs_hcon = hchan->conn;
4758 chan->hs_hcon->l2cap_data = chan->conn;
4759 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4760 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4761
4762 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4763 } else {
4764 /* Wait for logical link to be ready */
4765 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4766 }
4767 } else {
4768 /* Logical link not available */
4769 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4770 }
4771}
4772
4773static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4774{
4775 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4776 u8 rsp_result;
4777 if (result == -EINVAL)
4778 rsp_result = L2CAP_MR_BAD_ID;
4779 else
4780 rsp_result = L2CAP_MR_NOT_ALLOWED;
4781
4782 l2cap_send_move_chan_rsp(chan, rsp_result);
4783 }
4784
4785 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4786 chan->move_state = L2CAP_MOVE_STABLE;
4787
4788 /* Restart data transmission */
4789 l2cap_ertm_send(chan);
4790}
4791
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004792/* Invoke with locked chan */
4793void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004794{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004795 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004796 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004797
Mat Martineau8eb200b2012-10-23 15:24:17 -07004798 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4799 chan, result, local_amp_id, remote_amp_id);
4800
Mat Martineau8eb200b2012-10-23 15:24:17 -07004801 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4802 l2cap_chan_unlock(chan);
4803 return;
4804 }
4805
4806 if (chan->state != BT_CONNECTED) {
4807 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4808 } else if (result != L2CAP_MR_SUCCESS) {
4809 l2cap_do_move_cancel(chan, result);
4810 } else {
4811 switch (chan->move_role) {
4812 case L2CAP_MOVE_ROLE_INITIATOR:
4813 l2cap_do_move_initiate(chan, local_amp_id,
4814 remote_amp_id);
4815 break;
4816 case L2CAP_MOVE_ROLE_RESPONDER:
4817 l2cap_do_move_respond(chan, result);
4818 break;
4819 default:
4820 l2cap_do_move_cancel(chan, result);
4821 break;
4822 }
4823 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004824}
4825
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004826static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004827 struct l2cap_cmd_hdr *cmd,
4828 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004829{
4830 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004831 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004832 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004833 u16 icid = 0;
4834 u16 result = L2CAP_MR_NOT_ALLOWED;
4835
4836 if (cmd_len != sizeof(*req))
4837 return -EPROTO;
4838
4839 icid = le16_to_cpu(req->icid);
4840
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004841 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004842
Marcel Holtmann848566b2013-10-01 22:59:22 -07004843 if (!conn->hs_enabled)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004844 return -EINVAL;
4845
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004846 chan = l2cap_get_chan_by_dcid(conn, icid);
4847 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004848 rsp.icid = cpu_to_le16(icid);
4849 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4850 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4851 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004852 return 0;
4853 }
4854
Mat Martineau1500109b2012-10-23 15:24:15 -07004855 chan->ident = cmd->ident;
4856
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004857 if (chan->scid < L2CAP_CID_DYN_START ||
4858 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4859 (chan->mode != L2CAP_MODE_ERTM &&
4860 chan->mode != L2CAP_MODE_STREAMING)) {
4861 result = L2CAP_MR_NOT_ALLOWED;
4862 goto send_move_response;
4863 }
4864
4865 if (chan->local_amp_id == req->dest_amp_id) {
4866 result = L2CAP_MR_SAME_ID;
4867 goto send_move_response;
4868 }
4869
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004870 if (req->dest_amp_id != AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004871 struct hci_dev *hdev;
4872 hdev = hci_dev_get(req->dest_amp_id);
4873 if (!hdev || hdev->dev_type != HCI_AMP ||
4874 !test_bit(HCI_UP, &hdev->flags)) {
4875 if (hdev)
4876 hci_dev_put(hdev);
4877
4878 result = L2CAP_MR_BAD_ID;
4879 goto send_move_response;
4880 }
4881 hci_dev_put(hdev);
4882 }
4883
4884 /* Detect a move collision. Only send a collision response
4885 * if this side has "lost", otherwise proceed with the move.
4886 * The winner has the larger bd_addr.
4887 */
4888 if ((__chan_is_moving(chan) ||
4889 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
Marcel Holtmann6f59b902013-10-13 05:24:01 -07004890 bacmp(&conn->hcon->src, &conn->hcon->dst) > 0) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004891 result = L2CAP_MR_COLLISION;
4892 goto send_move_response;
4893 }
4894
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004895 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4896 l2cap_move_setup(chan);
4897 chan->move_id = req->dest_amp_id;
4898 icid = chan->dcid;
4899
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004900 if (req->dest_amp_id == AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004901 /* Moving to BR/EDR */
4902 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4903 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4904 result = L2CAP_MR_PEND;
4905 } else {
4906 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4907 result = L2CAP_MR_SUCCESS;
4908 }
4909 } else {
4910 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4911 /* Placeholder - uncomment when amp functions are available */
4912 /*amp_accept_physical(chan, req->dest_amp_id);*/
4913 result = L2CAP_MR_PEND;
4914 }
4915
4916send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004917 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004918
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004919 l2cap_chan_unlock(chan);
4920
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004921 return 0;
4922}
4923
Mat Martineau5b155ef2012-10-23 15:24:14 -07004924static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4925{
4926 struct l2cap_chan *chan;
4927 struct hci_chan *hchan = NULL;
4928
4929 chan = l2cap_get_chan_by_scid(conn, icid);
4930 if (!chan) {
4931 l2cap_send_move_chan_cfm_icid(conn, icid);
4932 return;
4933 }
4934
4935 __clear_chan_timer(chan);
4936 if (result == L2CAP_MR_PEND)
4937 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4938
4939 switch (chan->move_state) {
4940 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4941 /* Move confirm will be sent when logical link
4942 * is complete.
4943 */
4944 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4945 break;
4946 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4947 if (result == L2CAP_MR_PEND) {
4948 break;
4949 } else if (test_bit(CONN_LOCAL_BUSY,
4950 &chan->conn_state)) {
4951 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4952 } else {
4953 /* Logical link is up or moving to BR/EDR,
4954 * proceed with move
4955 */
4956 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4957 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4958 }
4959 break;
4960 case L2CAP_MOVE_WAIT_RSP:
4961 /* Moving to AMP */
4962 if (result == L2CAP_MR_SUCCESS) {
4963 /* Remote is ready, send confirm immediately
4964 * after logical link is ready
4965 */
4966 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4967 } else {
4968 /* Both logical link and move success
4969 * are required to confirm
4970 */
4971 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
4972 }
4973
4974 /* Placeholder - get hci_chan for logical link */
4975 if (!hchan) {
4976 /* Logical link not available */
4977 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4978 break;
4979 }
4980
4981 /* If the logical link is not yet connected, do not
4982 * send confirmation.
4983 */
4984 if (hchan->state != BT_CONNECTED)
4985 break;
4986
4987 /* Logical link is already ready to go */
4988
4989 chan->hs_hcon = hchan->conn;
4990 chan->hs_hcon->l2cap_data = chan->conn;
4991
4992 if (result == L2CAP_MR_SUCCESS) {
4993 /* Can confirm now */
4994 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4995 } else {
4996 /* Now only need move success
4997 * to confirm
4998 */
4999 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
5000 }
5001
5002 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5003 break;
5004 default:
5005 /* Any other amp move state means the move failed. */
5006 chan->move_id = chan->local_amp_id;
5007 l2cap_move_done(chan);
5008 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5009 }
5010
5011 l2cap_chan_unlock(chan);
5012}
5013
5014static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5015 u16 result)
5016{
5017 struct l2cap_chan *chan;
5018
5019 chan = l2cap_get_chan_by_ident(conn, ident);
5020 if (!chan) {
5021 /* Could not locate channel, icid is best guess */
5022 l2cap_send_move_chan_cfm_icid(conn, icid);
5023 return;
5024 }
5025
5026 __clear_chan_timer(chan);
5027
5028 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5029 if (result == L2CAP_MR_COLLISION) {
5030 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5031 } else {
5032 /* Cleanup - cancel move */
5033 chan->move_id = chan->local_amp_id;
5034 l2cap_move_done(chan);
5035 }
5036 }
5037
5038 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5039
5040 l2cap_chan_unlock(chan);
5041}
5042
5043static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5044 struct l2cap_cmd_hdr *cmd,
5045 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005046{
5047 struct l2cap_move_chan_rsp *rsp = data;
5048 u16 icid, result;
5049
5050 if (cmd_len != sizeof(*rsp))
5051 return -EPROTO;
5052
5053 icid = le16_to_cpu(rsp->icid);
5054 result = le16_to_cpu(rsp->result);
5055
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005056 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005057
Mat Martineau5b155ef2012-10-23 15:24:14 -07005058 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5059 l2cap_move_continue(conn, icid, result);
5060 else
5061 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005062
5063 return 0;
5064}
5065
Mat Martineau5f3847a2012-10-23 15:24:12 -07005066static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5067 struct l2cap_cmd_hdr *cmd,
5068 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005069{
5070 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005071 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005072 u16 icid, result;
5073
5074 if (cmd_len != sizeof(*cfm))
5075 return -EPROTO;
5076
5077 icid = le16_to_cpu(cfm->icid);
5078 result = le16_to_cpu(cfm->result);
5079
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005080 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005081
Mat Martineau5f3847a2012-10-23 15:24:12 -07005082 chan = l2cap_get_chan_by_dcid(conn, icid);
5083 if (!chan) {
5084 /* Spec requires a response even if the icid was not found */
5085 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5086 return 0;
5087 }
5088
5089 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5090 if (result == L2CAP_MC_CONFIRMED) {
5091 chan->local_amp_id = chan->move_id;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005092 if (chan->local_amp_id == AMP_ID_BREDR)
Mat Martineau5f3847a2012-10-23 15:24:12 -07005093 __release_logical_link(chan);
5094 } else {
5095 chan->move_id = chan->local_amp_id;
5096 }
5097
5098 l2cap_move_done(chan);
5099 }
5100
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005101 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5102
Mat Martineau5f3847a2012-10-23 15:24:12 -07005103 l2cap_chan_unlock(chan);
5104
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005105 return 0;
5106}
5107
5108static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005109 struct l2cap_cmd_hdr *cmd,
5110 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005111{
5112 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005113 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005114 u16 icid;
5115
5116 if (cmd_len != sizeof(*rsp))
5117 return -EPROTO;
5118
5119 icid = le16_to_cpu(rsp->icid);
5120
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005121 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005122
Mat Martineau3fd71a02012-10-23 15:24:16 -07005123 chan = l2cap_get_chan_by_scid(conn, icid);
5124 if (!chan)
5125 return 0;
5126
5127 __clear_chan_timer(chan);
5128
5129 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5130 chan->local_amp_id = chan->move_id;
5131
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005132 if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan)
Mat Martineau3fd71a02012-10-23 15:24:16 -07005133 __release_logical_link(chan);
5134
5135 l2cap_move_done(chan);
5136 }
5137
5138 l2cap_chan_unlock(chan);
5139
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005140 return 0;
5141}
5142
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005143static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005144 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005145{
5146 u16 max_latency;
5147
5148 if (min > max || min < 6 || max > 3200)
5149 return -EINVAL;
5150
5151 if (to_multiplier < 10 || to_multiplier > 3200)
5152 return -EINVAL;
5153
5154 if (max >= to_multiplier * 8)
5155 return -EINVAL;
5156
5157 max_latency = (to_multiplier * 8 / max) - 1;
5158 if (latency > 499 || latency > max_latency)
5159 return -EINVAL;
5160
5161 return 0;
5162}
5163
5164static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005165 struct l2cap_cmd_hdr *cmd,
5166 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005167{
5168 struct hci_conn *hcon = conn->hcon;
5169 struct l2cap_conn_param_update_req *req;
5170 struct l2cap_conn_param_update_rsp rsp;
5171 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005172 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005173
5174 if (!(hcon->link_mode & HCI_LM_MASTER))
5175 return -EINVAL;
5176
5177 cmd_len = __le16_to_cpu(cmd->len);
5178 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5179 return -EPROTO;
5180
5181 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005182 min = __le16_to_cpu(req->min);
5183 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005184 latency = __le16_to_cpu(req->latency);
5185 to_multiplier = __le16_to_cpu(req->to_multiplier);
5186
5187 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 +01005188 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005189
5190 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005191
5192 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5193 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005194 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005195 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005196 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005197
5198 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005199 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005200
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005201 if (!err)
5202 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5203
Claudio Takahaside731152011-02-11 19:28:55 -02005204 return 0;
5205}
5206
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005207static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005208 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5209 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005210{
5211 int err = 0;
5212
5213 switch (cmd->code) {
5214 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005215 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005216 break;
5217
5218 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005219 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005220 break;
5221
5222 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005223 case L2CAP_CREATE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005224 l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005225 break;
5226
5227 case L2CAP_CONF_REQ:
5228 err = l2cap_config_req(conn, cmd, cmd_len, data);
5229 break;
5230
5231 case L2CAP_CONF_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005232 l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005233 break;
5234
5235 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005236 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005237 break;
5238
5239 case L2CAP_DISCONN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005240 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005241 break;
5242
5243 case L2CAP_ECHO_REQ:
5244 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5245 break;
5246
5247 case L2CAP_ECHO_RSP:
5248 break;
5249
5250 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005251 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005252 break;
5253
5254 case L2CAP_INFO_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005255 l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005256 break;
5257
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005258 case L2CAP_CREATE_CHAN_REQ:
5259 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5260 break;
5261
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005262 case L2CAP_MOVE_CHAN_REQ:
5263 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5264 break;
5265
5266 case L2CAP_MOVE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005267 l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005268 break;
5269
5270 case L2CAP_MOVE_CHAN_CFM:
5271 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5272 break;
5273
5274 case L2CAP_MOVE_CHAN_CFM_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005275 l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005276 break;
5277
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005278 default:
5279 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5280 err = -EINVAL;
5281 break;
5282 }
5283
5284 return err;
5285}
5286
5287static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005288 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005289{
5290 switch (cmd->code) {
5291 case L2CAP_COMMAND_REJ:
5292 return 0;
5293
5294 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02005295 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005296
5297 case L2CAP_CONN_PARAM_UPDATE_RSP:
5298 return 0;
5299
5300 default:
5301 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5302 return -EINVAL;
5303 }
5304}
5305
Johan Hedberg7c2005d2013-09-16 13:05:16 +03005306static __le16 l2cap_err_to_reason(int err)
5307{
5308 switch (err) {
5309 case -EBADSLT:
5310 return __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
5311 case -EMSGSIZE:
5312 return __constant_cpu_to_le16(L2CAP_REJ_MTU_EXCEEDED);
5313 case -EINVAL:
5314 case -EPROTO:
5315 default:
5316 return __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
5317 }
5318}
5319
Johan Hedbergc5623552013-04-29 19:35:33 +03005320static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5321 struct sk_buff *skb)
5322{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005323 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005324 struct l2cap_cmd_hdr *cmd;
5325 u16 len;
Johan Hedbergc5623552013-04-29 19:35:33 +03005326 int err;
5327
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005328 if (hcon->type != LE_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005329 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005330
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005331 if (skb->len < L2CAP_CMD_HDR_SIZE)
5332 goto drop;
Johan Hedbergc5623552013-04-29 19:35:33 +03005333
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005334 cmd = (void *) skb->data;
5335 skb_pull(skb, L2CAP_CMD_HDR_SIZE);
Johan Hedbergc5623552013-04-29 19:35:33 +03005336
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005337 len = le16_to_cpu(cmd->len);
Johan Hedbergc5623552013-04-29 19:35:33 +03005338
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005339 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, cmd->ident);
Johan Hedbergc5623552013-04-29 19:35:33 +03005340
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005341 if (len != skb->len || !cmd->ident) {
5342 BT_DBG("corrupted command");
5343 goto drop;
5344 }
Johan Hedbergc5623552013-04-29 19:35:33 +03005345
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005346 err = l2cap_le_sig_cmd(conn, cmd, skb->data);
5347 if (err) {
5348 struct l2cap_cmd_rej_unk rej;
Johan Hedbergc5623552013-04-29 19:35:33 +03005349
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005350 BT_ERR("Wrong link type (%d)", err);
Johan Hedbergc5623552013-04-29 19:35:33 +03005351
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005352 rej.reason = l2cap_err_to_reason(err);
5353 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
5354 sizeof(rej), &rej);
Johan Hedbergc5623552013-04-29 19:35:33 +03005355 }
5356
Marcel Holtmann3b166292013-10-02 08:28:21 -07005357drop:
Johan Hedbergc5623552013-04-29 19:35:33 +03005358 kfree_skb(skb);
5359}
5360
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005361static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005362 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005363{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005364 struct hci_conn *hcon = conn->hcon;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005365 u8 *data = skb->data;
5366 int len = skb->len;
5367 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005368 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005369
5370 l2cap_raw_recv(conn, skb);
5371
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005372 if (hcon->type != ACL_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005373 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005374
Linus Torvalds1da177e2005-04-16 15:20:36 -07005375 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005376 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005377 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5378 data += L2CAP_CMD_HDR_SIZE;
5379 len -= L2CAP_CMD_HDR_SIZE;
5380
Al Viro88219a02007-07-29 00:17:25 -07005381 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005382
Gustavo Padovan2d792812012-10-06 10:07:01 +01005383 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5384 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005385
Al Viro88219a02007-07-29 00:17:25 -07005386 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005387 BT_DBG("corrupted command");
5388 break;
5389 }
5390
Johan Hedbergc5623552013-04-29 19:35:33 +03005391 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005392 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005393 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005394
5395 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005396
Johan Hedberg7c2005d2013-09-16 13:05:16 +03005397 rej.reason = l2cap_err_to_reason(err);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005398 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5399 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005400 }
5401
Al Viro88219a02007-07-29 00:17:25 -07005402 data += cmd_len;
5403 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005404 }
5405
Marcel Holtmann3b166292013-10-02 08:28:21 -07005406drop:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005407 kfree_skb(skb);
5408}
5409
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005410static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005411{
5412 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005413 int hdr_size;
5414
5415 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5416 hdr_size = L2CAP_EXT_HDR_SIZE;
5417 else
5418 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005419
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005420 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005421 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005422 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5423 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5424
5425 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005426 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005427 }
5428 return 0;
5429}
5430
Mat Martineau6ea00482012-05-17 20:53:52 -07005431static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005432{
Mat Martineaue31f7632012-05-17 20:53:41 -07005433 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005434
Mat Martineaue31f7632012-05-17 20:53:41 -07005435 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005436
Mat Martineaue31f7632012-05-17 20:53:41 -07005437 memset(&control, 0, sizeof(control));
5438 control.sframe = 1;
5439 control.final = 1;
5440 control.reqseq = chan->buffer_seq;
5441 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005442
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005443 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005444 control.super = L2CAP_SUPER_RNR;
5445 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005446 }
5447
Mat Martineaue31f7632012-05-17 20:53:41 -07005448 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5449 chan->unacked_frames > 0)
5450 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005451
Mat Martineaue31f7632012-05-17 20:53:41 -07005452 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005453 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005454
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005455 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005456 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5457 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5458 * send it now.
5459 */
5460 control.super = L2CAP_SUPER_RR;
5461 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005462 }
5463}
5464
Gustavo Padovan2d792812012-10-06 10:07:01 +01005465static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5466 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005467{
Mat Martineau84084a32011-07-22 14:54:00 -07005468 /* skb->len reflects data in skb as well as all fragments
5469 * skb->data_len reflects only data in fragments
5470 */
5471 if (!skb_has_frag_list(skb))
5472 skb_shinfo(skb)->frag_list = new_frag;
5473
5474 new_frag->next = NULL;
5475
5476 (*last_frag)->next = new_frag;
5477 *last_frag = new_frag;
5478
5479 skb->len += new_frag->len;
5480 skb->data_len += new_frag->len;
5481 skb->truesize += new_frag->truesize;
5482}
5483
Mat Martineau4b51dae92012-05-17 20:53:37 -07005484static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5485 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005486{
5487 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005488
Mat Martineau4b51dae92012-05-17 20:53:37 -07005489 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005490 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005491 if (chan->sdu)
5492 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005493
Gustavo Padovan80b98022012-05-27 22:27:51 -03005494 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005495 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005496
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005497 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005498 if (chan->sdu)
5499 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005500
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005501 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005502 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005503
Mat Martineau84084a32011-07-22 14:54:00 -07005504 if (chan->sdu_len > chan->imtu) {
5505 err = -EMSGSIZE;
5506 break;
5507 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005508
Mat Martineau84084a32011-07-22 14:54:00 -07005509 if (skb->len >= chan->sdu_len)
5510 break;
5511
5512 chan->sdu = skb;
5513 chan->sdu_last_frag = skb;
5514
5515 skb = NULL;
5516 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005517 break;
5518
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005519 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005520 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005521 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005522
Mat Martineau84084a32011-07-22 14:54:00 -07005523 append_skb_frag(chan->sdu, skb,
5524 &chan->sdu_last_frag);
5525 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005526
Mat Martineau84084a32011-07-22 14:54:00 -07005527 if (chan->sdu->len >= chan->sdu_len)
5528 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005529
Mat Martineau84084a32011-07-22 14:54:00 -07005530 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005531 break;
5532
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005533 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005534 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005535 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005536
Mat Martineau84084a32011-07-22 14:54:00 -07005537 append_skb_frag(chan->sdu, skb,
5538 &chan->sdu_last_frag);
5539 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005540
Mat Martineau84084a32011-07-22 14:54:00 -07005541 if (chan->sdu->len != chan->sdu_len)
5542 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005543
Gustavo Padovan80b98022012-05-27 22:27:51 -03005544 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005545
Mat Martineau84084a32011-07-22 14:54:00 -07005546 if (!err) {
5547 /* Reassembly complete */
5548 chan->sdu = NULL;
5549 chan->sdu_last_frag = NULL;
5550 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005551 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005552 break;
5553 }
5554
Mat Martineau84084a32011-07-22 14:54:00 -07005555 if (err) {
5556 kfree_skb(skb);
5557 kfree_skb(chan->sdu);
5558 chan->sdu = NULL;
5559 chan->sdu_last_frag = NULL;
5560 chan->sdu_len = 0;
5561 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005562
Mat Martineau84084a32011-07-22 14:54:00 -07005563 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005564}
5565
Mat Martineau32b32732012-10-23 15:24:11 -07005566static int l2cap_resegment(struct l2cap_chan *chan)
5567{
5568 /* Placeholder */
5569 return 0;
5570}
5571
Mat Martineaue3281402011-07-07 09:39:02 -07005572void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03005573{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005574 u8 event;
5575
5576 if (chan->mode != L2CAP_MODE_ERTM)
5577 return;
5578
5579 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005580 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005581}
5582
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005583static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5584{
Mat Martineau63838722012-05-17 20:53:45 -07005585 int err = 0;
5586 /* Pass sequential frames to l2cap_reassemble_sdu()
5587 * until a gap is encountered.
5588 */
5589
5590 BT_DBG("chan %p", chan);
5591
5592 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5593 struct sk_buff *skb;
5594 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5595 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5596
5597 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5598
5599 if (!skb)
5600 break;
5601
5602 skb_unlink(skb, &chan->srej_q);
5603 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5604 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5605 if (err)
5606 break;
5607 }
5608
5609 if (skb_queue_empty(&chan->srej_q)) {
5610 chan->rx_state = L2CAP_RX_STATE_RECV;
5611 l2cap_send_ack(chan);
5612 }
5613
5614 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005615}
5616
5617static void l2cap_handle_srej(struct l2cap_chan *chan,
5618 struct l2cap_ctrl *control)
5619{
Mat Martineauf80842a2012-05-17 20:53:46 -07005620 struct sk_buff *skb;
5621
5622 BT_DBG("chan %p, control %p", chan, control);
5623
5624 if (control->reqseq == chan->next_tx_seq) {
5625 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005626 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005627 return;
5628 }
5629
5630 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5631
5632 if (skb == NULL) {
5633 BT_DBG("Seq %d not available for retransmission",
5634 control->reqseq);
5635 return;
5636 }
5637
5638 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5639 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005640 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005641 return;
5642 }
5643
5644 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5645
5646 if (control->poll) {
5647 l2cap_pass_to_tx(chan, control);
5648
5649 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5650 l2cap_retransmit(chan, control);
5651 l2cap_ertm_send(chan);
5652
5653 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5654 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5655 chan->srej_save_reqseq = control->reqseq;
5656 }
5657 } else {
5658 l2cap_pass_to_tx_fbit(chan, control);
5659
5660 if (control->final) {
5661 if (chan->srej_save_reqseq != control->reqseq ||
5662 !test_and_clear_bit(CONN_SREJ_ACT,
5663 &chan->conn_state))
5664 l2cap_retransmit(chan, control);
5665 } else {
5666 l2cap_retransmit(chan, control);
5667 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5668 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5669 chan->srej_save_reqseq = control->reqseq;
5670 }
5671 }
5672 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005673}
5674
5675static void l2cap_handle_rej(struct l2cap_chan *chan,
5676 struct l2cap_ctrl *control)
5677{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005678 struct sk_buff *skb;
5679
5680 BT_DBG("chan %p, control %p", chan, control);
5681
5682 if (control->reqseq == chan->next_tx_seq) {
5683 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005684 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005685 return;
5686 }
5687
5688 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5689
5690 if (chan->max_tx && skb &&
5691 bt_cb(skb)->control.retries >= chan->max_tx) {
5692 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005693 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005694 return;
5695 }
5696
5697 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5698
5699 l2cap_pass_to_tx(chan, control);
5700
5701 if (control->final) {
5702 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5703 l2cap_retransmit_all(chan, control);
5704 } else {
5705 l2cap_retransmit_all(chan, control);
5706 l2cap_ertm_send(chan);
5707 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5708 set_bit(CONN_REJ_ACT, &chan->conn_state);
5709 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005710}
5711
Mat Martineau4b51dae92012-05-17 20:53:37 -07005712static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5713{
5714 BT_DBG("chan %p, txseq %d", chan, txseq);
5715
5716 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5717 chan->expected_tx_seq);
5718
5719 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5720 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005721 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005722 /* See notes below regarding "double poll" and
5723 * invalid packets.
5724 */
5725 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5726 BT_DBG("Invalid/Ignore - after SREJ");
5727 return L2CAP_TXSEQ_INVALID_IGNORE;
5728 } else {
5729 BT_DBG("Invalid - in window after SREJ sent");
5730 return L2CAP_TXSEQ_INVALID;
5731 }
5732 }
5733
5734 if (chan->srej_list.head == txseq) {
5735 BT_DBG("Expected SREJ");
5736 return L2CAP_TXSEQ_EXPECTED_SREJ;
5737 }
5738
5739 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5740 BT_DBG("Duplicate SREJ - txseq already stored");
5741 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5742 }
5743
5744 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5745 BT_DBG("Unexpected SREJ - not requested");
5746 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5747 }
5748 }
5749
5750 if (chan->expected_tx_seq == txseq) {
5751 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5752 chan->tx_win) {
5753 BT_DBG("Invalid - txseq outside tx window");
5754 return L2CAP_TXSEQ_INVALID;
5755 } else {
5756 BT_DBG("Expected");
5757 return L2CAP_TXSEQ_EXPECTED;
5758 }
5759 }
5760
5761 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01005762 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005763 BT_DBG("Duplicate - expected_tx_seq later than txseq");
5764 return L2CAP_TXSEQ_DUPLICATE;
5765 }
5766
5767 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
5768 /* A source of invalid packets is a "double poll" condition,
5769 * where delays cause us to send multiple poll packets. If
5770 * the remote stack receives and processes both polls,
5771 * sequence numbers can wrap around in such a way that a
5772 * resent frame has a sequence number that looks like new data
5773 * with a sequence gap. This would trigger an erroneous SREJ
5774 * request.
5775 *
5776 * Fortunately, this is impossible with a tx window that's
5777 * less than half of the maximum sequence number, which allows
5778 * invalid frames to be safely ignored.
5779 *
5780 * With tx window sizes greater than half of the tx window
5781 * maximum, the frame is invalid and cannot be ignored. This
5782 * causes a disconnect.
5783 */
5784
5785 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5786 BT_DBG("Invalid/Ignore - txseq outside tx window");
5787 return L2CAP_TXSEQ_INVALID_IGNORE;
5788 } else {
5789 BT_DBG("Invalid - txseq outside tx window");
5790 return L2CAP_TXSEQ_INVALID;
5791 }
5792 } else {
5793 BT_DBG("Unexpected - txseq indicates missing frames");
5794 return L2CAP_TXSEQ_UNEXPECTED;
5795 }
5796}
5797
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005798static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5799 struct l2cap_ctrl *control,
5800 struct sk_buff *skb, u8 event)
5801{
5802 int err = 0;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005803 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005804
5805 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5806 event);
5807
5808 switch (event) {
5809 case L2CAP_EV_RECV_IFRAME:
5810 switch (l2cap_classify_txseq(chan, control->txseq)) {
5811 case L2CAP_TXSEQ_EXPECTED:
5812 l2cap_pass_to_tx(chan, control);
5813
5814 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5815 BT_DBG("Busy, discarding expected seq %d",
5816 control->txseq);
5817 break;
5818 }
5819
5820 chan->expected_tx_seq = __next_seq(chan,
5821 control->txseq);
5822
5823 chan->buffer_seq = chan->expected_tx_seq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005824 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005825
5826 err = l2cap_reassemble_sdu(chan, skb, control);
5827 if (err)
5828 break;
5829
5830 if (control->final) {
5831 if (!test_and_clear_bit(CONN_REJ_ACT,
5832 &chan->conn_state)) {
5833 control->final = 0;
5834 l2cap_retransmit_all(chan, control);
5835 l2cap_ertm_send(chan);
5836 }
5837 }
5838
5839 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5840 l2cap_send_ack(chan);
5841 break;
5842 case L2CAP_TXSEQ_UNEXPECTED:
5843 l2cap_pass_to_tx(chan, control);
5844
5845 /* Can't issue SREJ frames in the local busy state.
5846 * Drop this frame, it will be seen as missing
5847 * when local busy is exited.
5848 */
5849 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5850 BT_DBG("Busy, discarding unexpected seq %d",
5851 control->txseq);
5852 break;
5853 }
5854
5855 /* There was a gap in the sequence, so an SREJ
5856 * must be sent for each missing frame. The
5857 * current frame is stored for later use.
5858 */
5859 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005860 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005861 BT_DBG("Queued %p (queue len %d)", skb,
5862 skb_queue_len(&chan->srej_q));
5863
5864 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5865 l2cap_seq_list_clear(&chan->srej_list);
5866 l2cap_send_srej(chan, control->txseq);
5867
5868 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5869 break;
5870 case L2CAP_TXSEQ_DUPLICATE:
5871 l2cap_pass_to_tx(chan, control);
5872 break;
5873 case L2CAP_TXSEQ_INVALID_IGNORE:
5874 break;
5875 case L2CAP_TXSEQ_INVALID:
5876 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005877 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005878 break;
5879 }
5880 break;
5881 case L2CAP_EV_RECV_RR:
5882 l2cap_pass_to_tx(chan, control);
5883 if (control->final) {
5884 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5885
Mat Martineaue6a3ee62012-10-23 15:24:22 -07005886 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
5887 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005888 control->final = 0;
5889 l2cap_retransmit_all(chan, control);
5890 }
5891
5892 l2cap_ertm_send(chan);
5893 } else if (control->poll) {
5894 l2cap_send_i_or_rr_or_rnr(chan);
5895 } else {
5896 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5897 &chan->conn_state) &&
5898 chan->unacked_frames)
5899 __set_retrans_timer(chan);
5900
5901 l2cap_ertm_send(chan);
5902 }
5903 break;
5904 case L2CAP_EV_RECV_RNR:
5905 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5906 l2cap_pass_to_tx(chan, control);
5907 if (control && control->poll) {
5908 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5909 l2cap_send_rr_or_rnr(chan, 0);
5910 }
5911 __clear_retrans_timer(chan);
5912 l2cap_seq_list_clear(&chan->retrans_list);
5913 break;
5914 case L2CAP_EV_RECV_REJ:
5915 l2cap_handle_rej(chan, control);
5916 break;
5917 case L2CAP_EV_RECV_SREJ:
5918 l2cap_handle_srej(chan, control);
5919 break;
5920 default:
5921 break;
5922 }
5923
5924 if (skb && !skb_in_use) {
5925 BT_DBG("Freeing %p", skb);
5926 kfree_skb(skb);
5927 }
5928
5929 return err;
5930}
5931
5932static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5933 struct l2cap_ctrl *control,
5934 struct sk_buff *skb, u8 event)
5935{
5936 int err = 0;
5937 u16 txseq = control->txseq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005938 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005939
5940 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5941 event);
5942
5943 switch (event) {
5944 case L2CAP_EV_RECV_IFRAME:
5945 switch (l2cap_classify_txseq(chan, txseq)) {
5946 case L2CAP_TXSEQ_EXPECTED:
5947 /* Keep frame for reassembly later */
5948 l2cap_pass_to_tx(chan, control);
5949 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005950 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005951 BT_DBG("Queued %p (queue len %d)", skb,
5952 skb_queue_len(&chan->srej_q));
5953
5954 chan->expected_tx_seq = __next_seq(chan, txseq);
5955 break;
5956 case L2CAP_TXSEQ_EXPECTED_SREJ:
5957 l2cap_seq_list_pop(&chan->srej_list);
5958
5959 l2cap_pass_to_tx(chan, control);
5960 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005961 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005962 BT_DBG("Queued %p (queue len %d)", skb,
5963 skb_queue_len(&chan->srej_q));
5964
5965 err = l2cap_rx_queued_iframes(chan);
5966 if (err)
5967 break;
5968
5969 break;
5970 case L2CAP_TXSEQ_UNEXPECTED:
5971 /* Got a frame that can't be reassembled yet.
5972 * Save it for later, and send SREJs to cover
5973 * the missing frames.
5974 */
5975 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005976 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005977 BT_DBG("Queued %p (queue len %d)", skb,
5978 skb_queue_len(&chan->srej_q));
5979
5980 l2cap_pass_to_tx(chan, control);
5981 l2cap_send_srej(chan, control->txseq);
5982 break;
5983 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
5984 /* This frame was requested with an SREJ, but
5985 * some expected retransmitted frames are
5986 * missing. Request retransmission of missing
5987 * SREJ'd frames.
5988 */
5989 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005990 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005991 BT_DBG("Queued %p (queue len %d)", skb,
5992 skb_queue_len(&chan->srej_q));
5993
5994 l2cap_pass_to_tx(chan, control);
5995 l2cap_send_srej_list(chan, control->txseq);
5996 break;
5997 case L2CAP_TXSEQ_DUPLICATE_SREJ:
5998 /* We've already queued this frame. Drop this copy. */
5999 l2cap_pass_to_tx(chan, control);
6000 break;
6001 case L2CAP_TXSEQ_DUPLICATE:
6002 /* Expecting a later sequence number, so this frame
6003 * was already received. Ignore it completely.
6004 */
6005 break;
6006 case L2CAP_TXSEQ_INVALID_IGNORE:
6007 break;
6008 case L2CAP_TXSEQ_INVALID:
6009 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006010 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006011 break;
6012 }
6013 break;
6014 case L2CAP_EV_RECV_RR:
6015 l2cap_pass_to_tx(chan, control);
6016 if (control->final) {
6017 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6018
6019 if (!test_and_clear_bit(CONN_REJ_ACT,
6020 &chan->conn_state)) {
6021 control->final = 0;
6022 l2cap_retransmit_all(chan, control);
6023 }
6024
6025 l2cap_ertm_send(chan);
6026 } else if (control->poll) {
6027 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6028 &chan->conn_state) &&
6029 chan->unacked_frames) {
6030 __set_retrans_timer(chan);
6031 }
6032
6033 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6034 l2cap_send_srej_tail(chan);
6035 } else {
6036 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6037 &chan->conn_state) &&
6038 chan->unacked_frames)
6039 __set_retrans_timer(chan);
6040
6041 l2cap_send_ack(chan);
6042 }
6043 break;
6044 case L2CAP_EV_RECV_RNR:
6045 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6046 l2cap_pass_to_tx(chan, control);
6047 if (control->poll) {
6048 l2cap_send_srej_tail(chan);
6049 } else {
6050 struct l2cap_ctrl rr_control;
6051 memset(&rr_control, 0, sizeof(rr_control));
6052 rr_control.sframe = 1;
6053 rr_control.super = L2CAP_SUPER_RR;
6054 rr_control.reqseq = chan->buffer_seq;
6055 l2cap_send_sframe(chan, &rr_control);
6056 }
6057
6058 break;
6059 case L2CAP_EV_RECV_REJ:
6060 l2cap_handle_rej(chan, control);
6061 break;
6062 case L2CAP_EV_RECV_SREJ:
6063 l2cap_handle_srej(chan, control);
6064 break;
6065 }
6066
6067 if (skb && !skb_in_use) {
6068 BT_DBG("Freeing %p", skb);
6069 kfree_skb(skb);
6070 }
6071
6072 return err;
6073}
6074
Mat Martineau32b32732012-10-23 15:24:11 -07006075static int l2cap_finish_move(struct l2cap_chan *chan)
6076{
6077 BT_DBG("chan %p", chan);
6078
6079 chan->rx_state = L2CAP_RX_STATE_RECV;
6080
6081 if (chan->hs_hcon)
6082 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6083 else
6084 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6085
6086 return l2cap_resegment(chan);
6087}
6088
6089static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6090 struct l2cap_ctrl *control,
6091 struct sk_buff *skb, u8 event)
6092{
6093 int err;
6094
6095 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6096 event);
6097
6098 if (!control->poll)
6099 return -EPROTO;
6100
6101 l2cap_process_reqseq(chan, control->reqseq);
6102
6103 if (!skb_queue_empty(&chan->tx_q))
6104 chan->tx_send_head = skb_peek(&chan->tx_q);
6105 else
6106 chan->tx_send_head = NULL;
6107
6108 /* Rewind next_tx_seq to the point expected
6109 * by the receiver.
6110 */
6111 chan->next_tx_seq = control->reqseq;
6112 chan->unacked_frames = 0;
6113
6114 err = l2cap_finish_move(chan);
6115 if (err)
6116 return err;
6117
6118 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6119 l2cap_send_i_or_rr_or_rnr(chan);
6120
6121 if (event == L2CAP_EV_RECV_IFRAME)
6122 return -EPROTO;
6123
6124 return l2cap_rx_state_recv(chan, control, NULL, event);
6125}
6126
6127static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6128 struct l2cap_ctrl *control,
6129 struct sk_buff *skb, u8 event)
6130{
6131 int err;
6132
6133 if (!control->final)
6134 return -EPROTO;
6135
6136 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6137
6138 chan->rx_state = L2CAP_RX_STATE_RECV;
6139 l2cap_process_reqseq(chan, control->reqseq);
6140
6141 if (!skb_queue_empty(&chan->tx_q))
6142 chan->tx_send_head = skb_peek(&chan->tx_q);
6143 else
6144 chan->tx_send_head = NULL;
6145
6146 /* Rewind next_tx_seq to the point expected
6147 * by the receiver.
6148 */
6149 chan->next_tx_seq = control->reqseq;
6150 chan->unacked_frames = 0;
6151
6152 if (chan->hs_hcon)
6153 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6154 else
6155 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6156
6157 err = l2cap_resegment(chan);
6158
6159 if (!err)
6160 err = l2cap_rx_state_recv(chan, control, skb, event);
6161
6162 return err;
6163}
6164
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006165static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6166{
6167 /* Make sure reqseq is for a packet that has been sent but not acked */
6168 u16 unacked;
6169
6170 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6171 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6172}
6173
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006174static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6175 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006176{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006177 int err = 0;
6178
6179 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6180 control, skb, event, chan->rx_state);
6181
6182 if (__valid_reqseq(chan, control->reqseq)) {
6183 switch (chan->rx_state) {
6184 case L2CAP_RX_STATE_RECV:
6185 err = l2cap_rx_state_recv(chan, control, skb, event);
6186 break;
6187 case L2CAP_RX_STATE_SREJ_SENT:
6188 err = l2cap_rx_state_srej_sent(chan, control, skb,
6189 event);
6190 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006191 case L2CAP_RX_STATE_WAIT_P:
6192 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6193 break;
6194 case L2CAP_RX_STATE_WAIT_F:
6195 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6196 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006197 default:
6198 /* shut it down */
6199 break;
6200 }
6201 } else {
6202 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6203 control->reqseq, chan->next_tx_seq,
6204 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006205 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006206 }
6207
6208 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006209}
6210
6211static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6212 struct sk_buff *skb)
6213{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006214 int err = 0;
6215
6216 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6217 chan->rx_state);
6218
6219 if (l2cap_classify_txseq(chan, control->txseq) ==
6220 L2CAP_TXSEQ_EXPECTED) {
6221 l2cap_pass_to_tx(chan, control);
6222
6223 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6224 __next_seq(chan, chan->buffer_seq));
6225
6226 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6227
6228 l2cap_reassemble_sdu(chan, skb, control);
6229 } else {
6230 if (chan->sdu) {
6231 kfree_skb(chan->sdu);
6232 chan->sdu = NULL;
6233 }
6234 chan->sdu_last_frag = NULL;
6235 chan->sdu_len = 0;
6236
6237 if (skb) {
6238 BT_DBG("Freeing %p", skb);
6239 kfree_skb(skb);
6240 }
6241 }
6242
6243 chan->last_acked_seq = control->txseq;
6244 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6245
6246 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006247}
6248
6249static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6250{
6251 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6252 u16 len;
6253 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006254
Mat Martineaub76bbd62012-04-11 10:48:43 -07006255 __unpack_control(chan, skb);
6256
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006257 len = skb->len;
6258
6259 /*
6260 * We can just drop the corrupted I-frame here.
6261 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006262 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006263 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006264 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006265 goto drop;
6266
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006267 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006268 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006269
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006270 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006271 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006272
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006273 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006274 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006275 goto drop;
6276 }
6277
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006278 if (!control->sframe) {
6279 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006280
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006281 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6282 control->sar, control->reqseq, control->final,
6283 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006284
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006285 /* Validate F-bit - F=0 always valid, F=1 only
6286 * valid in TX WAIT_F
6287 */
6288 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006289 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006290
6291 if (chan->mode != L2CAP_MODE_STREAMING) {
6292 event = L2CAP_EV_RECV_IFRAME;
6293 err = l2cap_rx(chan, control, skb, event);
6294 } else {
6295 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006296 }
6297
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006298 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006299 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006300 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006301 const u8 rx_func_to_event[4] = {
6302 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6303 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6304 };
6305
6306 /* Only I-frames are expected in streaming mode */
6307 if (chan->mode == L2CAP_MODE_STREAMING)
6308 goto drop;
6309
6310 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6311 control->reqseq, control->final, control->poll,
6312 control->super);
6313
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006314 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006315 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006316 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006317 goto drop;
6318 }
6319
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006320 /* Validate F and P bits */
6321 if (control->final && (control->poll ||
6322 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6323 goto drop;
6324
6325 event = rx_func_to_event[control->super];
6326 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006327 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006328 }
6329
6330 return 0;
6331
6332drop:
6333 kfree_skb(skb);
6334 return 0;
6335}
6336
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006337static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6338 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006339{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006340 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006341
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006342 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006343 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006344 if (cid == L2CAP_CID_A2MP) {
6345 chan = a2mp_channel_create(conn, skb);
6346 if (!chan) {
6347 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006348 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006349 }
6350
6351 l2cap_chan_lock(chan);
6352 } else {
6353 BT_DBG("unknown cid 0x%4.4x", cid);
6354 /* Drop packet and return */
6355 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006356 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006357 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006358 }
6359
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006360 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006361
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006362 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006363 goto drop;
6364
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006365 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006366 case L2CAP_MODE_BASIC:
6367 /* If socket recv buffers overflows we drop data here
6368 * which is *bad* because L2CAP has to be reliable.
6369 * But we don't have any other choice. L2CAP doesn't
6370 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006371
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006372 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006373 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006374
Gustavo Padovan80b98022012-05-27 22:27:51 -03006375 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006376 goto done;
6377 break;
6378
6379 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006380 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006381 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006382 goto done;
6383
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006384 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006385 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006386 break;
6387 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006388
6389drop:
6390 kfree_skb(skb);
6391
6392done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006393 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006394}
6395
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006396static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6397 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006398{
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006399 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006400 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006401
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006402 if (hcon->type != ACL_LINK)
6403 goto drop;
6404
Marcel Holtmann6f59b902013-10-13 05:24:01 -07006405 chan = l2cap_global_chan_by_psm(0, psm, &conn->hcon->src,
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07006406 &conn->hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006407 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006408 goto drop;
6409
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006410 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006411
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006412 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006413 goto drop;
6414
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006415 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006416 goto drop;
6417
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006418 /* Store remote BD_ADDR and PSM for msg_name */
6419 bacpy(&bt_cb(skb)->bdaddr, &conn->hcon->dst);
6420 bt_cb(skb)->psm = psm;
6421
Gustavo Padovan80b98022012-05-27 22:27:51 -03006422 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006423 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006424
6425drop:
6426 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006427}
6428
Marcel Holtmann72f78352013-04-23 00:59:00 -07006429static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006430 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006431{
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006432 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006433 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006434
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006435 if (hcon->type != LE_LINK)
6436 goto drop;
6437
Johan Hedbergaf1c0132013-04-29 19:35:42 +03006438 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann6f59b902013-10-13 05:24:01 -07006439 &conn->hcon->src, &conn->hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006440 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006441 goto drop;
6442
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006443 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006444
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006445 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006446 goto drop;
6447
Gustavo Padovan80b98022012-05-27 22:27:51 -03006448 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006449 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006450
6451drop:
6452 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006453}
6454
Linus Torvalds1da177e2005-04-16 15:20:36 -07006455static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6456{
6457 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006458 u16 cid, len;
6459 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006460
6461 skb_pull(skb, L2CAP_HDR_SIZE);
6462 cid = __le16_to_cpu(lh->cid);
6463 len = __le16_to_cpu(lh->len);
6464
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006465 if (len != skb->len) {
6466 kfree_skb(skb);
6467 return;
6468 }
6469
Linus Torvalds1da177e2005-04-16 15:20:36 -07006470 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6471
6472 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006473 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006474 l2cap_sig_channel(conn, skb);
6475 break;
6476
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006477 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006478 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006479 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006480 l2cap_conless_channel(conn, psm, skb);
6481 break;
6482
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006483 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006484 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006485 break;
6486
Marcel Holtmanna2877622013-10-02 23:46:54 -07006487 case L2CAP_CID_LE_SIGNALING:
6488 l2cap_le_sig_channel(conn, skb);
6489 break;
6490
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006491 case L2CAP_CID_SMP:
6492 if (smp_sig_channel(conn, skb))
6493 l2cap_conn_del(conn->hcon, EACCES);
6494 break;
6495
Linus Torvalds1da177e2005-04-16 15:20:36 -07006496 default:
6497 l2cap_data_channel(conn, cid, skb);
6498 break;
6499 }
6500}
6501
6502/* ---- L2CAP interface with lower layer (HCI) ---- */
6503
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006504int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006505{
6506 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006507 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006508
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006509 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006510
6511 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006512 read_lock(&chan_list_lock);
6513 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006514 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006515 continue;
6516
Marcel Holtmann7eafc592013-10-13 08:12:47 -07006517 if (!bacmp(&c->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006518 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006519 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006520 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006521 exact++;
Marcel Holtmann7eafc592013-10-13 08:12:47 -07006522 } else if (!bacmp(&c->src, BDADDR_ANY)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006523 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006524 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006525 lm2 |= HCI_LM_MASTER;
6526 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006527 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006528 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006529
6530 return exact ? lm1 : lm2;
6531}
6532
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006533void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006534{
Marcel Holtmann01394182006-07-03 10:02:46 +02006535 struct l2cap_conn *conn;
6536
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006537 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006538
Linus Torvalds1da177e2005-04-16 15:20:36 -07006539 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03006540 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006541 if (conn)
6542 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006543 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006544 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006545 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006546}
6547
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006548int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006549{
6550 struct l2cap_conn *conn = hcon->l2cap_data;
6551
6552 BT_DBG("hcon %p", hcon);
6553
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006554 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006555 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006556 return conn->disc_reason;
6557}
6558
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006559void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006560{
6561 BT_DBG("hcon %p reason %d", hcon, reason);
6562
Joe Perchese1750722011-06-29 18:18:29 -07006563 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006564}
6565
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006566static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006567{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006568 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006569 return;
6570
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006571 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006572 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006573 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006574 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006575 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006576 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006577 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006578 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006579 }
6580}
6581
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006582int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006583{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006584 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006585 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006586
Marcel Holtmann01394182006-07-03 10:02:46 +02006587 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006588 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006589
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006590 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006591
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006592 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306593 if (!status && encrypt)
6594 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006595 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006596 }
6597
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006598 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006599
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006600 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006601 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006602
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006603 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6604 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006605
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006606 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6607 l2cap_chan_unlock(chan);
6608 continue;
6609 }
6610
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006611 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006612 if (!status && encrypt) {
6613 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006614 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006615 }
6616
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006617 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006618 continue;
6619 }
6620
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006621 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006622 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006623 continue;
6624 }
6625
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006626 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006627 chan->state == BT_CONFIG)) {
Marcel Holtmannd97c8992013-10-14 02:53:54 -07006628 chan->ops->resume(chan);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006629 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006630 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006631 continue;
6632 }
6633
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006634 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006635 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006636 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006637 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006638 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006639 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006640 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006641 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006642 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006643 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006644
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006645 lock_sock(sk);
6646
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006647 if (!status) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07006648 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006649 res = L2CAP_CR_PEND;
6650 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006651 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006652 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006653 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006654 res = L2CAP_CR_SUCCESS;
6655 stat = L2CAP_CS_NO_INFO;
6656 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006657 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006658 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006659 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006660 res = L2CAP_CR_SEC_BLOCK;
6661 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006662 }
6663
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006664 release_sock(sk);
6665
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006666 rsp.scid = cpu_to_le16(chan->dcid);
6667 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006668 rsp.result = cpu_to_le16(res);
6669 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006670 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006671 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006672
6673 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6674 res == L2CAP_CR_SUCCESS) {
6675 char buf[128];
6676 set_bit(CONF_REQ_SENT, &chan->conf_state);
6677 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6678 L2CAP_CONF_REQ,
6679 l2cap_build_conf_req(chan, buf),
6680 buf);
6681 chan->num_conf_req++;
6682 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006683 }
6684
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006685 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006686 }
6687
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006688 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006689
Linus Torvalds1da177e2005-04-16 15:20:36 -07006690 return 0;
6691}
6692
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006693int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006694{
6695 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006696 struct l2cap_hdr *hdr;
6697 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006698
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006699 /* For AMP controller do not create l2cap conn */
6700 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6701 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006702
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006703 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03006704 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006705
6706 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006707 goto drop;
6708
6709 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6710
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006711 switch (flags) {
6712 case ACL_START:
6713 case ACL_START_NO_FLUSH:
6714 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006715 if (conn->rx_len) {
6716 BT_ERR("Unexpected start frame (len %d)", skb->len);
6717 kfree_skb(conn->rx_skb);
6718 conn->rx_skb = NULL;
6719 conn->rx_len = 0;
6720 l2cap_conn_unreliable(conn, ECOMM);
6721 }
6722
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006723 /* Start fragment always begin with Basic L2CAP header */
6724 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006725 BT_ERR("Frame is too short (len %d)", skb->len);
6726 l2cap_conn_unreliable(conn, ECOMM);
6727 goto drop;
6728 }
6729
6730 hdr = (struct l2cap_hdr *) skb->data;
6731 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6732
6733 if (len == skb->len) {
6734 /* Complete frame received */
6735 l2cap_recv_frame(conn, skb);
6736 return 0;
6737 }
6738
6739 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6740
6741 if (skb->len > len) {
6742 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006743 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006744 l2cap_conn_unreliable(conn, ECOMM);
6745 goto drop;
6746 }
6747
6748 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006749 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006750 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006751 goto drop;
6752
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006753 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006754 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006755 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006756 break;
6757
6758 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006759 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6760
6761 if (!conn->rx_len) {
6762 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6763 l2cap_conn_unreliable(conn, ECOMM);
6764 goto drop;
6765 }
6766
6767 if (skb->len > conn->rx_len) {
6768 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006769 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006770 kfree_skb(conn->rx_skb);
6771 conn->rx_skb = NULL;
6772 conn->rx_len = 0;
6773 l2cap_conn_unreliable(conn, ECOMM);
6774 goto drop;
6775 }
6776
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006777 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006778 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006779 conn->rx_len -= skb->len;
6780
6781 if (!conn->rx_len) {
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02006782 /* Complete frame received. l2cap_recv_frame
6783 * takes ownership of the skb so set the global
6784 * rx_skb pointer to NULL first.
6785 */
6786 struct sk_buff *rx_skb = conn->rx_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006787 conn->rx_skb = NULL;
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02006788 l2cap_recv_frame(conn, rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006789 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006790 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006791 }
6792
6793drop:
6794 kfree_skb(skb);
6795 return 0;
6796}
6797
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006798static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006799{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006800 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006801
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006802 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006803
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006804 list_for_each_entry(c, &chan_list, global_l) {
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006805 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 -07006806 &c->src, &c->dst,
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006807 c->state, __le16_to_cpu(c->psm),
6808 c->scid, c->dcid, c->imtu, c->omtu,
6809 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006810 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006811
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006812 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006813
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006814 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006815}
6816
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006817static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6818{
6819 return single_open(file, l2cap_debugfs_show, inode->i_private);
6820}
6821
6822static const struct file_operations l2cap_debugfs_fops = {
6823 .open = l2cap_debugfs_open,
6824 .read = seq_read,
6825 .llseek = seq_lseek,
6826 .release = single_release,
6827};
6828
6829static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006830
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006831int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006832{
6833 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006834
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006835 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006836 if (err < 0)
6837 return err;
6838
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006839 if (bt_debugfs) {
Gustavo Padovan2d792812012-10-06 10:07:01 +01006840 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6841 NULL, &l2cap_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006842 if (!l2cap_debugfs)
6843 BT_ERR("Failed to create L2CAP debug file");
6844 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006845
Linus Torvalds1da177e2005-04-16 15:20:36 -07006846 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006847}
6848
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006849void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006850{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006851 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006852 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006853}
6854
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006855module_param(disable_ertm, bool, 0644);
6856MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");