blob: 97572970fba2231ec45173b9f4fb7c15a494b4d7 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
Gustavo F. Padovance5706b2010-07-13 11:57:11 -03004 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
Gustavo F. Padovan5d8868f2010-07-16 16:18:39 -03005 Copyright (C) 2010 Google Inc.
Gustavo F. Padovan590051d2011-12-18 13:39:33 -02006 Copyright (C) 2011 ProFUSION Embedded Systems
Mat Martineau422e9252012-04-27 16:50:55 -07007 Copyright (c) 2012 Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07008
9 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License version 2 as
13 published by the Free Software Foundation;
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
18 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090019 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090024 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
25 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070026 SOFTWARE IS DISCLAIMED.
27*/
28
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020029/* Bluetooth L2CAP core. */
Linus Torvalds1da177e2005-04-16 15:20:36 -070030
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/module.h>
32
Marcel Holtmannaef7d972010-03-21 05:27:45 +010033#include <linux/debugfs.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030034#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36#include <net/bluetooth/bluetooth.h>
37#include <net/bluetooth/hci_core.h>
38#include <net/bluetooth/l2cap.h>
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070039
Marcel Holtmannac4b7232013-10-10 14:54:16 -070040#include "smp.h"
Marcel Holtmann70247282013-10-10 14:54:15 -070041#include "a2mp.h"
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070042#include "amp.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
Mat Martineaud1de6d42012-05-17 20:53:55 -070044bool disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020045
Marcel Holtmann547d1032013-10-12 08:18:19 -070046static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN | L2CAP_FEAT_UCD;
Marcel Holtmannd40bffb2013-10-12 08:18:18 -070047static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP | L2CAP_FC_CONNLESS, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
Johannes Bergb5ad8b72011-06-01 08:54:45 +020049static LIST_HEAD(chan_list);
50static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
Linus Torvalds1da177e2005-04-16 15:20:36 -070052static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +010053 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030054static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
Gustavo Padovan2d792812012-10-06 10:07:01 +010055 void *data);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -030056static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +020057static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
Gustavo Padovand6603662012-05-21 13:58:22 -030059static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
Gustavo Padovan2d792812012-10-06 10:07:01 +010060 struct sk_buff_head *skbs, u8 event);
Mat Martineau608bcc62012-05-17 20:53:32 -070061
Marcel Holtmann4f1654e2013-10-13 08:50:41 -070062static inline __u8 bdaddr_type(struct hci_conn *hcon, __u8 type)
63{
64 if (hcon->type == LE_LINK) {
65 if (type == ADDR_LE_DEV_PUBLIC)
66 return BDADDR_LE_PUBLIC;
67 else
68 return BDADDR_LE_RANDOM;
69 }
70
71 return BDADDR_BREDR;
72}
73
Marcel Holtmann01394182006-07-03 10:02:46 +020074/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030075
Gustavo Padovan2d792812012-10-06 10:07:01 +010076static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
77 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020078{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020079 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030080
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020081 list_for_each_entry(c, &conn->chan_l, list) {
82 if (c->dcid == cid)
83 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020084 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020085 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020086}
87
Gustavo Padovan2d792812012-10-06 10:07:01 +010088static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
89 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020090{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020091 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030092
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020093 list_for_each_entry(c, &conn->chan_l, list) {
94 if (c->scid == cid)
95 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020096 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020097 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020098}
99
100/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -0700101 * Returns locked channel. */
Gustavo Padovan2d792812012-10-06 10:07:01 +0100102static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
103 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +0200104{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300105 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300106
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200107 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300108 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -0700109 if (c)
110 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200111 mutex_unlock(&conn->chan_lock);
112
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300113 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200114}
115
Mat Martineaub1a130b2012-10-23 15:24:09 -0700116/* Find channel with given DCID.
117 * Returns locked channel.
118 */
119static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
120 u16 cid)
121{
122 struct l2cap_chan *c;
123
124 mutex_lock(&conn->chan_lock);
125 c = __l2cap_get_chan_by_dcid(conn, cid);
126 if (c)
127 l2cap_chan_lock(c);
128 mutex_unlock(&conn->chan_lock);
129
130 return c;
131}
132
Gustavo Padovan2d792812012-10-06 10:07:01 +0100133static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
134 u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200135{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200136 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300137
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200138 list_for_each_entry(c, &conn->chan_l, list) {
139 if (c->ident == ident)
140 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200141 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200142 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200143}
144
Mat Martineau5b155ef2012-10-23 15:24:14 -0700145static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
146 u8 ident)
147{
148 struct l2cap_chan *c;
149
150 mutex_lock(&conn->chan_lock);
151 c = __l2cap_get_chan_by_ident(conn, ident);
152 if (c)
153 l2cap_chan_lock(c);
154 mutex_unlock(&conn->chan_lock);
155
156 return c;
157}
158
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300159static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300160{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300161 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300162
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300163 list_for_each_entry(c, &chan_list, global_l) {
Marcel Holtmann7eafc592013-10-13 08:12:47 -0700164 if (c->sport == psm && !bacmp(&c->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100165 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300166 }
Szymon Janc250938c2011-11-16 09:32:22 +0100167 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300168}
169
170int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
171{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300172 int err;
173
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200174 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300175
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300176 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300177 err = -EADDRINUSE;
178 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300179 }
180
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300181 if (psm) {
182 chan->psm = psm;
183 chan->sport = psm;
184 err = 0;
185 } else {
186 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300187
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300188 err = -EINVAL;
189 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300190 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300191 chan->psm = cpu_to_le16(p);
192 chan->sport = cpu_to_le16(p);
193 err = 0;
194 break;
195 }
196 }
197
198done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200199 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300200 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300201}
202
203int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
204{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200205 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300206
207 chan->scid = scid;
208
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200209 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300210
211 return 0;
212}
213
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300214static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200215{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300216 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200217
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300218 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300219 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200220 return cid;
221 }
222
223 return 0;
224}
225
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. Padovan710f9b0a2011-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. Padovan710f9b0a2011-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. Padovan710f9b0a2011-03-25 14:30:37 -03003613 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003614 u8 rsp_code;
Gustavo F. Padovan710f9b0a2011-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. Padovan710f9b0a2011-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. Padovan710f9b0a2011-03-25 14:30:37 -03003631 return;
3632
Gustavo F. Padovan710f9b0a2011-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. Padovan710f9b0a2011-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
Johan Hedberg662d6522013-10-16 11:20:47 +03003974static void cmd_reject_invalid_cid(struct l2cap_conn *conn, u8 ident,
3975 u16 scid, u16 dcid)
3976{
3977 struct l2cap_cmd_rej_cid rej;
3978
3979 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
3980 rej.scid = __cpu_to_le16(scid);
3981 rej.dcid = __cpu_to_le16(dcid);
3982
3983 l2cap_send_cmd(conn, ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
3984}
3985
Gustavo Padovan2d792812012-10-06 10:07:01 +01003986static inline int l2cap_config_req(struct l2cap_conn *conn,
3987 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3988 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003989{
3990 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3991 u16 dcid, flags;
3992 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003993 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003994 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003995
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003996 if (cmd_len < sizeof(*req))
3997 return -EPROTO;
3998
Linus Torvalds1da177e2005-04-16 15:20:36 -07003999 dcid = __le16_to_cpu(req->dcid);
4000 flags = __le16_to_cpu(req->flags);
4001
4002 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
4003
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004004 chan = l2cap_get_chan_by_scid(conn, dcid);
Johan Hedberg662d6522013-10-16 11:20:47 +03004005 if (!chan) {
4006 cmd_reject_invalid_cid(conn, cmd->ident, dcid, 0);
4007 return 0;
4008 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004009
David S. Miller033b1142011-07-21 13:38:42 -07004010 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Johan Hedberg662d6522013-10-16 11:20:47 +03004011 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4012 chan->dcid);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004013 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03004014 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01004015
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004016 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07004017 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004018 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004019 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004020 l2cap_build_conf_rsp(chan, rsp,
4021 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004022 goto unlock;
4023 }
4024
4025 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004026 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4027 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004028
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004029 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004030 /* Incomplete config. Send empty response. */
4031 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004032 l2cap_build_conf_rsp(chan, rsp,
4033 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004034 goto unlock;
4035 }
4036
4037 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004038 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004039 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004040 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004041 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004042 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004043
Mat Martineau1500109b2012-10-23 15:24:15 -07004044 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004045 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004046 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004047
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004048 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004049 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004050
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004051 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004052 goto unlock;
4053
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004054 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004055 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004056
Mat Martineau105bdf92012-04-27 16:50:48 -07004057 if (chan->mode == L2CAP_MODE_ERTM ||
4058 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004059 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004060
Mat Martineau3c588192012-04-11 10:48:42 -07004061 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004062 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004063 else
4064 l2cap_chan_ready(chan);
4065
Marcel Holtmann876d9482007-10-20 13:35:42 +02004066 goto unlock;
4067 }
4068
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004069 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004070 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004071 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004072 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004073 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004074 }
4075
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004076 /* Got Conf Rsp PENDING from remote side and asume we sent
4077 Conf Rsp PENDING in the code above */
4078 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004079 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004080
4081 /* check compatibility */
4082
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004083 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004084 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004085 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4086 else
4087 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004088 }
4089
Linus Torvalds1da177e2005-04-16 15:20:36 -07004090unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004091 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004092 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004093}
4094
Gustavo Padovan2d792812012-10-06 10:07:01 +01004095static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004096 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4097 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004098{
4099 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4100 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004101 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004102 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004103 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004104
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004105 if (cmd_len < sizeof(*rsp))
4106 return -EPROTO;
4107
Linus Torvalds1da177e2005-04-16 15:20:36 -07004108 scid = __le16_to_cpu(rsp->scid);
4109 flags = __le16_to_cpu(rsp->flags);
4110 result = __le16_to_cpu(rsp->result);
4111
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004112 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4113 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004114
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004115 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004116 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004117 return 0;
4118
4119 switch (result) {
4120 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004121 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004122 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004123 break;
4124
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004125 case L2CAP_CONF_PENDING:
4126 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4127
4128 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4129 char buf[64];
4130
4131 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004132 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004133 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004134 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004135 goto done;
4136 }
4137
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004138 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004139 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4140 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004141 } else {
4142 if (l2cap_check_efs(chan)) {
4143 amp_create_logical_link(chan);
4144 chan->ident = cmd->ident;
4145 }
4146 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004147 }
4148 goto done;
4149
Linus Torvalds1da177e2005-04-16 15:20:36 -07004150 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004151 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004152 char req[64];
4153
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004154 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004155 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004156 goto done;
4157 }
4158
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004159 /* throw out any old stored conf requests */
4160 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004161 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004162 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004163 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004164 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004165 goto done;
4166 }
4167
4168 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004169 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004170 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004171 if (result != L2CAP_CONF_SUCCESS)
4172 goto done;
4173 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004174 }
4175
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004176 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004177 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004178
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004179 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004180 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004181 goto done;
4182 }
4183
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004184 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004185 goto done;
4186
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004187 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004188
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004189 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004190 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004191
Mat Martineau105bdf92012-04-27 16:50:48 -07004192 if (chan->mode == L2CAP_MODE_ERTM ||
4193 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004194 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004195
Mat Martineau3c588192012-04-11 10:48:42 -07004196 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004197 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004198 else
4199 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004200 }
4201
4202done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004203 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004204 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004205}
4206
Gustavo Padovan2d792812012-10-06 10:07:01 +01004207static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004208 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4209 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004210{
4211 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4212 struct l2cap_disconn_rsp rsp;
4213 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004214 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004215
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004216 if (cmd_len != sizeof(*req))
4217 return -EPROTO;
4218
Linus Torvalds1da177e2005-04-16 15:20:36 -07004219 scid = __le16_to_cpu(req->scid);
4220 dcid = __le16_to_cpu(req->dcid);
4221
4222 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4223
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004224 mutex_lock(&conn->chan_lock);
4225
4226 chan = __l2cap_get_chan_by_scid(conn, dcid);
4227 if (!chan) {
4228 mutex_unlock(&conn->chan_lock);
Johan Hedberg662d6522013-10-16 11:20:47 +03004229 cmd_reject_invalid_cid(conn, cmd->ident, dcid, scid);
4230 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004231 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004232
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004233 l2cap_chan_lock(chan);
4234
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004235 rsp.dcid = cpu_to_le16(chan->scid);
4236 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004237 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4238
Gustavo Padovan5ec1bbe2013-10-15 19:24:48 -03004239 chan->ops->set_shutdown(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004240
Mat Martineau61d6ef32012-04-27 16:50:50 -07004241 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004242 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004243
4244 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004245
Gustavo Padovan80b98022012-05-27 22:27:51 -03004246 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004247 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004248
4249 mutex_unlock(&conn->chan_lock);
4250
Linus Torvalds1da177e2005-04-16 15:20:36 -07004251 return 0;
4252}
4253
Gustavo Padovan2d792812012-10-06 10:07:01 +01004254static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004255 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4256 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004257{
4258 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4259 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004260 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004261
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004262 if (cmd_len != sizeof(*rsp))
4263 return -EPROTO;
4264
Linus Torvalds1da177e2005-04-16 15:20:36 -07004265 scid = __le16_to_cpu(rsp->scid);
4266 dcid = __le16_to_cpu(rsp->dcid);
4267
4268 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4269
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004270 mutex_lock(&conn->chan_lock);
4271
4272 chan = __l2cap_get_chan_by_scid(conn, scid);
4273 if (!chan) {
4274 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004275 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004276 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004277
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004278 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004279
Mat Martineau61d6ef32012-04-27 16:50:50 -07004280 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004281 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004282
4283 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004284
Gustavo Padovan80b98022012-05-27 22:27:51 -03004285 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004286 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004287
4288 mutex_unlock(&conn->chan_lock);
4289
Linus Torvalds1da177e2005-04-16 15:20:36 -07004290 return 0;
4291}
4292
Gustavo Padovan2d792812012-10-06 10:07:01 +01004293static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004294 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4295 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004296{
4297 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004298 u16 type;
4299
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004300 if (cmd_len != sizeof(*req))
4301 return -EPROTO;
4302
Linus Torvalds1da177e2005-04-16 15:20:36 -07004303 type = __le16_to_cpu(req->type);
4304
4305 BT_DBG("type 0x%4.4x", type);
4306
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004307 if (type == L2CAP_IT_FEAT_MASK) {
4308 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004309 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004310 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004311 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4312 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004313 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004314 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004315 | L2CAP_FEAT_FCS;
Marcel Holtmann848566b2013-10-01 22:59:22 -07004316 if (conn->hs_enabled)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004317 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004318 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004319
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004320 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004321 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4322 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004323 } else if (type == L2CAP_IT_FIXED_CHAN) {
4324 u8 buf[12];
4325 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004326
Marcel Holtmann848566b2013-10-01 22:59:22 -07004327 if (conn->hs_enabled)
Mat Martineau50a147c2011-11-02 16:18:34 -07004328 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4329 else
4330 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4331
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004332 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4333 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004334 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004335 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4336 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004337 } else {
4338 struct l2cap_info_rsp rsp;
4339 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004340 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004341 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4342 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004343 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004344
4345 return 0;
4346}
4347
Gustavo Padovan2d792812012-10-06 10:07:01 +01004348static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004349 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4350 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004351{
4352 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4353 u16 type, result;
4354
Jaganath Kanakkassery3f6fa3d2013-06-21 19:55:11 +05304355 if (cmd_len < sizeof(*rsp))
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004356 return -EPROTO;
4357
Linus Torvalds1da177e2005-04-16 15:20:36 -07004358 type = __le16_to_cpu(rsp->type);
4359 result = __le16_to_cpu(rsp->result);
4360
4361 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4362
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004363 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4364 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004365 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004366 return 0;
4367
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004368 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004369
Ville Tervoadb08ed2010-08-04 09:43:33 +03004370 if (result != L2CAP_IR_SUCCESS) {
4371 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4372 conn->info_ident = 0;
4373
4374 l2cap_conn_start(conn);
4375
4376 return 0;
4377 }
4378
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004379 switch (type) {
4380 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004381 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004382
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004383 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004384 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004385 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004386
4387 conn->info_ident = l2cap_get_ident(conn);
4388
4389 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004390 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004391 } else {
4392 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4393 conn->info_ident = 0;
4394
4395 l2cap_conn_start(conn);
4396 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004397 break;
4398
4399 case L2CAP_IT_FIXED_CHAN:
4400 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004401 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004402 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004403
4404 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004405 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004406 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004407
Linus Torvalds1da177e2005-04-16 15:20:36 -07004408 return 0;
4409}
4410
Mat Martineau17009152012-10-23 15:24:07 -07004411static int l2cap_create_channel_req(struct l2cap_conn *conn,
4412 struct l2cap_cmd_hdr *cmd,
4413 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004414{
4415 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004416 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004417 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004418 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004419 u16 psm, scid;
4420
4421 if (cmd_len != sizeof(*req))
4422 return -EPROTO;
4423
Marcel Holtmann848566b2013-10-01 22:59:22 -07004424 if (!conn->hs_enabled)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004425 return -EINVAL;
4426
4427 psm = le16_to_cpu(req->psm);
4428 scid = le16_to_cpu(req->scid);
4429
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004430 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 -07004431
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004432 /* For controller id 0 make BR/EDR connection */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004433 if (req->amp_id == AMP_ID_BREDR) {
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004434 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4435 req->amp_id);
4436 return 0;
4437 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004438
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004439 /* Validate AMP controller id */
4440 hdev = hci_dev_get(req->amp_id);
4441 if (!hdev)
4442 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004443
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004444 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004445 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004446 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004447 }
4448
4449 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4450 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004451 if (chan) {
4452 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4453 struct hci_conn *hs_hcon;
4454
Marcel Holtmann98e0f7e2013-10-13 02:23:40 -07004455 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
4456 &conn->hcon->dst);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004457 if (!hs_hcon) {
4458 hci_dev_put(hdev);
Johan Hedberg662d6522013-10-16 11:20:47 +03004459 cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4460 chan->dcid);
4461 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004462 }
4463
4464 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4465
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004466 mgr->bredr_chan = chan;
4467 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004468 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004469 conn->mtu = hdev->block_mtu;
4470 }
4471
4472 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004473
4474 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004475
4476error:
4477 rsp.dcid = 0;
4478 rsp.scid = cpu_to_le16(scid);
4479 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4480 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4481
4482 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4483 sizeof(rsp), &rsp);
4484
Johan Hedbergdc280802013-09-16 13:05:13 +03004485 return 0;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004486}
4487
Mat Martineau8eb200b2012-10-23 15:24:17 -07004488static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4489{
4490 struct l2cap_move_chan_req req;
4491 u8 ident;
4492
4493 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4494
4495 ident = l2cap_get_ident(chan->conn);
4496 chan->ident = ident;
4497
4498 req.icid = cpu_to_le16(chan->scid);
4499 req.dest_amp_id = dest_amp_id;
4500
4501 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4502 &req);
4503
4504 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4505}
4506
Mat Martineau1500109b2012-10-23 15:24:15 -07004507static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004508{
4509 struct l2cap_move_chan_rsp rsp;
4510
Mat Martineau1500109b2012-10-23 15:24:15 -07004511 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004512
Mat Martineau1500109b2012-10-23 15:24:15 -07004513 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004514 rsp.result = cpu_to_le16(result);
4515
Mat Martineau1500109b2012-10-23 15:24:15 -07004516 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4517 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004518}
4519
Mat Martineau5b155ef2012-10-23 15:24:14 -07004520static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004521{
4522 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004523
Mat Martineau5b155ef2012-10-23 15:24:14 -07004524 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004525
Mat Martineau5b155ef2012-10-23 15:24:14 -07004526 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004527
Mat Martineau5b155ef2012-10-23 15:24:14 -07004528 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004529 cfm.result = cpu_to_le16(result);
4530
Mat Martineau5b155ef2012-10-23 15:24:14 -07004531 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4532 sizeof(cfm), &cfm);
4533
4534 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4535}
4536
4537static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4538{
4539 struct l2cap_move_chan_cfm cfm;
4540
4541 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4542
4543 cfm.icid = cpu_to_le16(icid);
4544 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4545
4546 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4547 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004548}
4549
4550static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004551 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004552{
4553 struct l2cap_move_chan_cfm_rsp rsp;
4554
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004555 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004556
4557 rsp.icid = cpu_to_le16(icid);
4558 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4559}
4560
Mat Martineau5f3847a2012-10-23 15:24:12 -07004561static void __release_logical_link(struct l2cap_chan *chan)
4562{
4563 chan->hs_hchan = NULL;
4564 chan->hs_hcon = NULL;
4565
4566 /* Placeholder - release the logical link */
4567}
4568
Mat Martineau1500109b2012-10-23 15:24:15 -07004569static void l2cap_logical_fail(struct l2cap_chan *chan)
4570{
4571 /* Logical link setup failed */
4572 if (chan->state != BT_CONNECTED) {
4573 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004574 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004575 return;
4576 }
4577
4578 switch (chan->move_role) {
4579 case L2CAP_MOVE_ROLE_RESPONDER:
4580 l2cap_move_done(chan);
4581 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4582 break;
4583 case L2CAP_MOVE_ROLE_INITIATOR:
4584 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4585 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4586 /* Remote has only sent pending or
4587 * success responses, clean up
4588 */
4589 l2cap_move_done(chan);
4590 }
4591
4592 /* Other amp move states imply that the move
4593 * has already aborted
4594 */
4595 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4596 break;
4597 }
4598}
4599
4600static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4601 struct hci_chan *hchan)
4602{
4603 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004604
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004605 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004606 chan->hs_hcon->l2cap_data = chan->conn;
4607
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004608 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004609
4610 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004611 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004612
4613 set_default_fcs(chan);
4614
4615 err = l2cap_ertm_init(chan);
4616 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004617 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004618 else
4619 l2cap_chan_ready(chan);
4620 }
4621}
4622
4623static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4624 struct hci_chan *hchan)
4625{
4626 chan->hs_hcon = hchan->conn;
4627 chan->hs_hcon->l2cap_data = chan->conn;
4628
4629 BT_DBG("move_state %d", chan->move_state);
4630
4631 switch (chan->move_state) {
4632 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4633 /* Move confirm will be sent after a success
4634 * response is received
4635 */
4636 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4637 break;
4638 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4639 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4640 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4641 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4642 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4643 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4644 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4645 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4646 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4647 }
4648 break;
4649 default:
4650 /* Move was not in expected state, free the channel */
4651 __release_logical_link(chan);
4652
4653 chan->move_state = L2CAP_MOVE_STABLE;
4654 }
4655}
4656
4657/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004658void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4659 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004660{
Mat Martineau1500109b2012-10-23 15:24:15 -07004661 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4662
4663 if (status) {
4664 l2cap_logical_fail(chan);
4665 __release_logical_link(chan);
4666 return;
4667 }
4668
4669 if (chan->state != BT_CONNECTED) {
4670 /* Ignore logical link if channel is on BR/EDR */
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004671 if (chan->local_amp_id != AMP_ID_BREDR)
Mat Martineau1500109b2012-10-23 15:24:15 -07004672 l2cap_logical_finish_create(chan, hchan);
4673 } else {
4674 l2cap_logical_finish_move(chan, hchan);
4675 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004676}
4677
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004678void l2cap_move_start(struct l2cap_chan *chan)
4679{
4680 BT_DBG("chan %p", chan);
4681
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004682 if (chan->local_amp_id == AMP_ID_BREDR) {
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004683 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4684 return;
4685 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4686 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4687 /* Placeholder - start physical link setup */
4688 } else {
4689 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4690 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4691 chan->move_id = 0;
4692 l2cap_move_setup(chan);
4693 l2cap_send_move_chan_req(chan, 0);
4694 }
4695}
4696
Mat Martineau8eb200b2012-10-23 15:24:17 -07004697static void l2cap_do_create(struct l2cap_chan *chan, int result,
4698 u8 local_amp_id, u8 remote_amp_id)
4699{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004700 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4701 local_amp_id, remote_amp_id);
4702
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004703 chan->fcs = L2CAP_FCS_NONE;
4704
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004705 /* Outgoing channel on AMP */
4706 if (chan->state == BT_CONNECT) {
4707 if (result == L2CAP_CR_SUCCESS) {
4708 chan->local_amp_id = local_amp_id;
4709 l2cap_send_create_chan_req(chan, remote_amp_id);
4710 } else {
4711 /* Revert to BR/EDR connect */
4712 l2cap_send_conn_req(chan);
4713 }
4714
4715 return;
4716 }
4717
4718 /* Incoming channel on AMP */
4719 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004720 struct l2cap_conn_rsp rsp;
4721 char buf[128];
4722 rsp.scid = cpu_to_le16(chan->dcid);
4723 rsp.dcid = cpu_to_le16(chan->scid);
4724
Mat Martineau8eb200b2012-10-23 15:24:17 -07004725 if (result == L2CAP_CR_SUCCESS) {
4726 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004727 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4728 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004729 } else {
4730 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004731 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4732 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004733 }
4734
4735 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4736 sizeof(rsp), &rsp);
4737
4738 if (result == L2CAP_CR_SUCCESS) {
4739 __l2cap_state_change(chan, BT_CONFIG);
4740 set_bit(CONF_REQ_SENT, &chan->conf_state);
4741 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4742 L2CAP_CONF_REQ,
4743 l2cap_build_conf_req(chan, buf), buf);
4744 chan->num_conf_req++;
4745 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004746 }
4747}
4748
4749static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4750 u8 remote_amp_id)
4751{
4752 l2cap_move_setup(chan);
4753 chan->move_id = local_amp_id;
4754 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4755
4756 l2cap_send_move_chan_req(chan, remote_amp_id);
4757}
4758
4759static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4760{
4761 struct hci_chan *hchan = NULL;
4762
4763 /* Placeholder - get hci_chan for logical link */
4764
4765 if (hchan) {
4766 if (hchan->state == BT_CONNECTED) {
4767 /* Logical link is ready to go */
4768 chan->hs_hcon = hchan->conn;
4769 chan->hs_hcon->l2cap_data = chan->conn;
4770 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4771 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4772
4773 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4774 } else {
4775 /* Wait for logical link to be ready */
4776 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4777 }
4778 } else {
4779 /* Logical link not available */
4780 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4781 }
4782}
4783
4784static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4785{
4786 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4787 u8 rsp_result;
4788 if (result == -EINVAL)
4789 rsp_result = L2CAP_MR_BAD_ID;
4790 else
4791 rsp_result = L2CAP_MR_NOT_ALLOWED;
4792
4793 l2cap_send_move_chan_rsp(chan, rsp_result);
4794 }
4795
4796 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4797 chan->move_state = L2CAP_MOVE_STABLE;
4798
4799 /* Restart data transmission */
4800 l2cap_ertm_send(chan);
4801}
4802
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004803/* Invoke with locked chan */
4804void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004805{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004806 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004807 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004808
Mat Martineau8eb200b2012-10-23 15:24:17 -07004809 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4810 chan, result, local_amp_id, remote_amp_id);
4811
Mat Martineau8eb200b2012-10-23 15:24:17 -07004812 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4813 l2cap_chan_unlock(chan);
4814 return;
4815 }
4816
4817 if (chan->state != BT_CONNECTED) {
4818 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4819 } else if (result != L2CAP_MR_SUCCESS) {
4820 l2cap_do_move_cancel(chan, result);
4821 } else {
4822 switch (chan->move_role) {
4823 case L2CAP_MOVE_ROLE_INITIATOR:
4824 l2cap_do_move_initiate(chan, local_amp_id,
4825 remote_amp_id);
4826 break;
4827 case L2CAP_MOVE_ROLE_RESPONDER:
4828 l2cap_do_move_respond(chan, result);
4829 break;
4830 default:
4831 l2cap_do_move_cancel(chan, result);
4832 break;
4833 }
4834 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004835}
4836
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004837static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004838 struct l2cap_cmd_hdr *cmd,
4839 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004840{
4841 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004842 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004843 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004844 u16 icid = 0;
4845 u16 result = L2CAP_MR_NOT_ALLOWED;
4846
4847 if (cmd_len != sizeof(*req))
4848 return -EPROTO;
4849
4850 icid = le16_to_cpu(req->icid);
4851
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004852 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004853
Marcel Holtmann848566b2013-10-01 22:59:22 -07004854 if (!conn->hs_enabled)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004855 return -EINVAL;
4856
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004857 chan = l2cap_get_chan_by_dcid(conn, icid);
4858 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004859 rsp.icid = cpu_to_le16(icid);
4860 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4861 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4862 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004863 return 0;
4864 }
4865
Mat Martineau1500109b2012-10-23 15:24:15 -07004866 chan->ident = cmd->ident;
4867
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004868 if (chan->scid < L2CAP_CID_DYN_START ||
4869 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4870 (chan->mode != L2CAP_MODE_ERTM &&
4871 chan->mode != L2CAP_MODE_STREAMING)) {
4872 result = L2CAP_MR_NOT_ALLOWED;
4873 goto send_move_response;
4874 }
4875
4876 if (chan->local_amp_id == req->dest_amp_id) {
4877 result = L2CAP_MR_SAME_ID;
4878 goto send_move_response;
4879 }
4880
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004881 if (req->dest_amp_id != AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004882 struct hci_dev *hdev;
4883 hdev = hci_dev_get(req->dest_amp_id);
4884 if (!hdev || hdev->dev_type != HCI_AMP ||
4885 !test_bit(HCI_UP, &hdev->flags)) {
4886 if (hdev)
4887 hci_dev_put(hdev);
4888
4889 result = L2CAP_MR_BAD_ID;
4890 goto send_move_response;
4891 }
4892 hci_dev_put(hdev);
4893 }
4894
4895 /* Detect a move collision. Only send a collision response
4896 * if this side has "lost", otherwise proceed with the move.
4897 * The winner has the larger bd_addr.
4898 */
4899 if ((__chan_is_moving(chan) ||
4900 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
Marcel Holtmann6f59b902013-10-13 05:24:01 -07004901 bacmp(&conn->hcon->src, &conn->hcon->dst) > 0) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004902 result = L2CAP_MR_COLLISION;
4903 goto send_move_response;
4904 }
4905
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004906 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4907 l2cap_move_setup(chan);
4908 chan->move_id = req->dest_amp_id;
4909 icid = chan->dcid;
4910
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07004911 if (req->dest_amp_id == AMP_ID_BREDR) {
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004912 /* Moving to BR/EDR */
4913 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4914 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4915 result = L2CAP_MR_PEND;
4916 } else {
4917 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4918 result = L2CAP_MR_SUCCESS;
4919 }
4920 } else {
4921 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4922 /* Placeholder - uncomment when amp functions are available */
4923 /*amp_accept_physical(chan, req->dest_amp_id);*/
4924 result = L2CAP_MR_PEND;
4925 }
4926
4927send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004928 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004929
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004930 l2cap_chan_unlock(chan);
4931
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004932 return 0;
4933}
4934
Mat Martineau5b155ef2012-10-23 15:24:14 -07004935static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4936{
4937 struct l2cap_chan *chan;
4938 struct hci_chan *hchan = NULL;
4939
4940 chan = l2cap_get_chan_by_scid(conn, icid);
4941 if (!chan) {
4942 l2cap_send_move_chan_cfm_icid(conn, icid);
4943 return;
4944 }
4945
4946 __clear_chan_timer(chan);
4947 if (result == L2CAP_MR_PEND)
4948 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4949
4950 switch (chan->move_state) {
4951 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4952 /* Move confirm will be sent when logical link
4953 * is complete.
4954 */
4955 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4956 break;
4957 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4958 if (result == L2CAP_MR_PEND) {
4959 break;
4960 } else if (test_bit(CONN_LOCAL_BUSY,
4961 &chan->conn_state)) {
4962 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4963 } else {
4964 /* Logical link is up or moving to BR/EDR,
4965 * proceed with move
4966 */
4967 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4968 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4969 }
4970 break;
4971 case L2CAP_MOVE_WAIT_RSP:
4972 /* Moving to AMP */
4973 if (result == L2CAP_MR_SUCCESS) {
4974 /* Remote is ready, send confirm immediately
4975 * after logical link is ready
4976 */
4977 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4978 } else {
4979 /* Both logical link and move success
4980 * are required to confirm
4981 */
4982 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
4983 }
4984
4985 /* Placeholder - get hci_chan for logical link */
4986 if (!hchan) {
4987 /* Logical link not available */
4988 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4989 break;
4990 }
4991
4992 /* If the logical link is not yet connected, do not
4993 * send confirmation.
4994 */
4995 if (hchan->state != BT_CONNECTED)
4996 break;
4997
4998 /* Logical link is already ready to go */
4999
5000 chan->hs_hcon = hchan->conn;
5001 chan->hs_hcon->l2cap_data = chan->conn;
5002
5003 if (result == L2CAP_MR_SUCCESS) {
5004 /* Can confirm now */
5005 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
5006 } else {
5007 /* Now only need move success
5008 * to confirm
5009 */
5010 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
5011 }
5012
5013 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
5014 break;
5015 default:
5016 /* Any other amp move state means the move failed. */
5017 chan->move_id = chan->local_amp_id;
5018 l2cap_move_done(chan);
5019 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5020 }
5021
5022 l2cap_chan_unlock(chan);
5023}
5024
5025static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5026 u16 result)
5027{
5028 struct l2cap_chan *chan;
5029
5030 chan = l2cap_get_chan_by_ident(conn, ident);
5031 if (!chan) {
5032 /* Could not locate channel, icid is best guess */
5033 l2cap_send_move_chan_cfm_icid(conn, icid);
5034 return;
5035 }
5036
5037 __clear_chan_timer(chan);
5038
5039 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5040 if (result == L2CAP_MR_COLLISION) {
5041 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5042 } else {
5043 /* Cleanup - cancel move */
5044 chan->move_id = chan->local_amp_id;
5045 l2cap_move_done(chan);
5046 }
5047 }
5048
5049 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5050
5051 l2cap_chan_unlock(chan);
5052}
5053
5054static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5055 struct l2cap_cmd_hdr *cmd,
5056 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005057{
5058 struct l2cap_move_chan_rsp *rsp = data;
5059 u16 icid, result;
5060
5061 if (cmd_len != sizeof(*rsp))
5062 return -EPROTO;
5063
5064 icid = le16_to_cpu(rsp->icid);
5065 result = le16_to_cpu(rsp->result);
5066
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005067 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005068
Mat Martineau5b155ef2012-10-23 15:24:14 -07005069 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5070 l2cap_move_continue(conn, icid, result);
5071 else
5072 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005073
5074 return 0;
5075}
5076
Mat Martineau5f3847a2012-10-23 15:24:12 -07005077static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5078 struct l2cap_cmd_hdr *cmd,
5079 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005080{
5081 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005082 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005083 u16 icid, result;
5084
5085 if (cmd_len != sizeof(*cfm))
5086 return -EPROTO;
5087
5088 icid = le16_to_cpu(cfm->icid);
5089 result = le16_to_cpu(cfm->result);
5090
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005091 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005092
Mat Martineau5f3847a2012-10-23 15:24:12 -07005093 chan = l2cap_get_chan_by_dcid(conn, icid);
5094 if (!chan) {
5095 /* Spec requires a response even if the icid was not found */
5096 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5097 return 0;
5098 }
5099
5100 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5101 if (result == L2CAP_MC_CONFIRMED) {
5102 chan->local_amp_id = chan->move_id;
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005103 if (chan->local_amp_id == AMP_ID_BREDR)
Mat Martineau5f3847a2012-10-23 15:24:12 -07005104 __release_logical_link(chan);
5105 } else {
5106 chan->move_id = chan->local_amp_id;
5107 }
5108
5109 l2cap_move_done(chan);
5110 }
5111
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005112 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5113
Mat Martineau5f3847a2012-10-23 15:24:12 -07005114 l2cap_chan_unlock(chan);
5115
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005116 return 0;
5117}
5118
5119static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005120 struct l2cap_cmd_hdr *cmd,
5121 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005122{
5123 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005124 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005125 u16 icid;
5126
5127 if (cmd_len != sizeof(*rsp))
5128 return -EPROTO;
5129
5130 icid = le16_to_cpu(rsp->icid);
5131
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005132 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005133
Mat Martineau3fd71a02012-10-23 15:24:16 -07005134 chan = l2cap_get_chan_by_scid(conn, icid);
5135 if (!chan)
5136 return 0;
5137
5138 __clear_chan_timer(chan);
5139
5140 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5141 chan->local_amp_id = chan->move_id;
5142
Marcel Holtmann6ed971c2013-10-05 11:47:44 -07005143 if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan)
Mat Martineau3fd71a02012-10-23 15:24:16 -07005144 __release_logical_link(chan);
5145
5146 l2cap_move_done(chan);
5147 }
5148
5149 l2cap_chan_unlock(chan);
5150
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005151 return 0;
5152}
5153
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005154static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005155 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005156{
5157 u16 max_latency;
5158
5159 if (min > max || min < 6 || max > 3200)
5160 return -EINVAL;
5161
5162 if (to_multiplier < 10 || to_multiplier > 3200)
5163 return -EINVAL;
5164
5165 if (max >= to_multiplier * 8)
5166 return -EINVAL;
5167
5168 max_latency = (to_multiplier * 8 / max) - 1;
5169 if (latency > 499 || latency > max_latency)
5170 return -EINVAL;
5171
5172 return 0;
5173}
5174
5175static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005176 struct l2cap_cmd_hdr *cmd,
5177 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005178{
5179 struct hci_conn *hcon = conn->hcon;
5180 struct l2cap_conn_param_update_req *req;
5181 struct l2cap_conn_param_update_rsp rsp;
5182 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005183 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005184
5185 if (!(hcon->link_mode & HCI_LM_MASTER))
5186 return -EINVAL;
5187
5188 cmd_len = __le16_to_cpu(cmd->len);
5189 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5190 return -EPROTO;
5191
5192 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005193 min = __le16_to_cpu(req->min);
5194 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005195 latency = __le16_to_cpu(req->latency);
5196 to_multiplier = __le16_to_cpu(req->to_multiplier);
5197
5198 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 +01005199 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005200
5201 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005202
5203 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5204 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005205 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005206 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005207 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005208
5209 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005210 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005211
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005212 if (!err)
5213 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5214
Claudio Takahaside731152011-02-11 19:28:55 -02005215 return 0;
5216}
5217
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005218static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005219 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5220 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005221{
5222 int err = 0;
5223
5224 switch (cmd->code) {
5225 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005226 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005227 break;
5228
5229 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005230 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005231 break;
5232
5233 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005234 case L2CAP_CREATE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005235 l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005236 break;
5237
5238 case L2CAP_CONF_REQ:
5239 err = l2cap_config_req(conn, cmd, cmd_len, data);
5240 break;
5241
5242 case L2CAP_CONF_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005243 l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005244 break;
5245
5246 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005247 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005248 break;
5249
5250 case L2CAP_DISCONN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005251 l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005252 break;
5253
5254 case L2CAP_ECHO_REQ:
5255 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5256 break;
5257
5258 case L2CAP_ECHO_RSP:
5259 break;
5260
5261 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005262 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005263 break;
5264
5265 case L2CAP_INFO_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005266 l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005267 break;
5268
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005269 case L2CAP_CREATE_CHAN_REQ:
5270 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5271 break;
5272
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005273 case L2CAP_MOVE_CHAN_REQ:
5274 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5275 break;
5276
5277 case L2CAP_MOVE_CHAN_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005278 l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005279 break;
5280
5281 case L2CAP_MOVE_CHAN_CFM:
5282 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5283 break;
5284
5285 case L2CAP_MOVE_CHAN_CFM_RSP:
Johan Hedberg9245e732013-09-16 13:05:17 +03005286 l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005287 break;
5288
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005289 default:
5290 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5291 err = -EINVAL;
5292 break;
5293 }
5294
5295 return err;
5296}
5297
5298static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005299 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005300{
5301 switch (cmd->code) {
5302 case L2CAP_COMMAND_REJ:
5303 return 0;
5304
5305 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02005306 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005307
5308 case L2CAP_CONN_PARAM_UPDATE_RSP:
5309 return 0;
5310
5311 default:
5312 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5313 return -EINVAL;
5314 }
5315}
5316
Johan Hedbergc5623552013-04-29 19:35:33 +03005317static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5318 struct sk_buff *skb)
5319{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005320 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005321 struct l2cap_cmd_hdr *cmd;
5322 u16 len;
Johan Hedbergc5623552013-04-29 19:35:33 +03005323 int err;
5324
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005325 if (hcon->type != LE_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005326 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005327
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005328 if (skb->len < L2CAP_CMD_HDR_SIZE)
5329 goto drop;
Johan Hedbergc5623552013-04-29 19:35:33 +03005330
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005331 cmd = (void *) skb->data;
5332 skb_pull(skb, L2CAP_CMD_HDR_SIZE);
Johan Hedbergc5623552013-04-29 19:35:33 +03005333
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005334 len = le16_to_cpu(cmd->len);
Johan Hedbergc5623552013-04-29 19:35:33 +03005335
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005336 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, cmd->ident);
Johan Hedbergc5623552013-04-29 19:35:33 +03005337
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005338 if (len != skb->len || !cmd->ident) {
5339 BT_DBG("corrupted command");
5340 goto drop;
5341 }
Johan Hedbergc5623552013-04-29 19:35:33 +03005342
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005343 err = l2cap_le_sig_cmd(conn, cmd, skb->data);
5344 if (err) {
5345 struct l2cap_cmd_rej_unk rej;
Johan Hedbergc5623552013-04-29 19:35:33 +03005346
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005347 BT_ERR("Wrong link type (%d)", err);
Johan Hedbergc5623552013-04-29 19:35:33 +03005348
Johan Hedberga5211492013-10-16 11:20:49 +03005349 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Marcel Holtmann4f3e2192013-10-03 01:26:37 -07005350 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
5351 sizeof(rej), &rej);
Johan Hedbergc5623552013-04-29 19:35:33 +03005352 }
5353
Marcel Holtmann3b166292013-10-02 08:28:21 -07005354drop:
Johan Hedbergc5623552013-04-29 19:35:33 +03005355 kfree_skb(skb);
5356}
5357
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005358static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005359 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005360{
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005361 struct hci_conn *hcon = conn->hcon;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005362 u8 *data = skb->data;
5363 int len = skb->len;
5364 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005365 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005366
5367 l2cap_raw_recv(conn, skb);
5368
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005369 if (hcon->type != ACL_LINK)
Marcel Holtmann3b166292013-10-02 08:28:21 -07005370 goto drop;
Johan Hedberg69c4e4e2013-09-16 13:05:18 +03005371
Linus Torvalds1da177e2005-04-16 15:20:36 -07005372 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005373 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005374 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5375 data += L2CAP_CMD_HDR_SIZE;
5376 len -= L2CAP_CMD_HDR_SIZE;
5377
Al Viro88219a02007-07-29 00:17:25 -07005378 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005379
Gustavo Padovan2d792812012-10-06 10:07:01 +01005380 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5381 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005382
Al Viro88219a02007-07-29 00:17:25 -07005383 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005384 BT_DBG("corrupted command");
5385 break;
5386 }
5387
Johan Hedbergc5623552013-04-29 19:35:33 +03005388 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005389 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005390 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005391
5392 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005393
Johan Hedberga5211492013-10-16 11:20:49 +03005394 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005395 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5396 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005397 }
5398
Al Viro88219a02007-07-29 00:17:25 -07005399 data += cmd_len;
5400 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005401 }
5402
Marcel Holtmann3b166292013-10-02 08:28:21 -07005403drop:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005404 kfree_skb(skb);
5405}
5406
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005407static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005408{
5409 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005410 int hdr_size;
5411
5412 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5413 hdr_size = L2CAP_EXT_HDR_SIZE;
5414 else
5415 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005416
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005417 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005418 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005419 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5420 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5421
5422 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005423 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005424 }
5425 return 0;
5426}
5427
Mat Martineau6ea00482012-05-17 20:53:52 -07005428static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005429{
Mat Martineaue31f7632012-05-17 20:53:41 -07005430 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005431
Mat Martineaue31f7632012-05-17 20:53:41 -07005432 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005433
Mat Martineaue31f7632012-05-17 20:53:41 -07005434 memset(&control, 0, sizeof(control));
5435 control.sframe = 1;
5436 control.final = 1;
5437 control.reqseq = chan->buffer_seq;
5438 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005439
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005440 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005441 control.super = L2CAP_SUPER_RNR;
5442 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005443 }
5444
Mat Martineaue31f7632012-05-17 20:53:41 -07005445 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5446 chan->unacked_frames > 0)
5447 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005448
Mat Martineaue31f7632012-05-17 20:53:41 -07005449 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005450 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005451
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005452 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005453 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5454 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5455 * send it now.
5456 */
5457 control.super = L2CAP_SUPER_RR;
5458 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005459 }
5460}
5461
Gustavo Padovan2d792812012-10-06 10:07:01 +01005462static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5463 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005464{
Mat Martineau84084a32011-07-22 14:54:00 -07005465 /* skb->len reflects data in skb as well as all fragments
5466 * skb->data_len reflects only data in fragments
5467 */
5468 if (!skb_has_frag_list(skb))
5469 skb_shinfo(skb)->frag_list = new_frag;
5470
5471 new_frag->next = NULL;
5472
5473 (*last_frag)->next = new_frag;
5474 *last_frag = new_frag;
5475
5476 skb->len += new_frag->len;
5477 skb->data_len += new_frag->len;
5478 skb->truesize += new_frag->truesize;
5479}
5480
Mat Martineau4b51dae92012-05-17 20:53:37 -07005481static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5482 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005483{
5484 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005485
Mat Martineau4b51dae92012-05-17 20:53:37 -07005486 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005487 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005488 if (chan->sdu)
5489 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005490
Gustavo Padovan80b98022012-05-27 22:27:51 -03005491 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005492 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005493
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005494 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005495 if (chan->sdu)
5496 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005497
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005498 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005499 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005500
Mat Martineau84084a32011-07-22 14:54:00 -07005501 if (chan->sdu_len > chan->imtu) {
5502 err = -EMSGSIZE;
5503 break;
5504 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005505
Mat Martineau84084a32011-07-22 14:54:00 -07005506 if (skb->len >= chan->sdu_len)
5507 break;
5508
5509 chan->sdu = skb;
5510 chan->sdu_last_frag = skb;
5511
5512 skb = NULL;
5513 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005514 break;
5515
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005516 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005517 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005518 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005519
Mat Martineau84084a32011-07-22 14:54:00 -07005520 append_skb_frag(chan->sdu, skb,
5521 &chan->sdu_last_frag);
5522 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005523
Mat Martineau84084a32011-07-22 14:54:00 -07005524 if (chan->sdu->len >= chan->sdu_len)
5525 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005526
Mat Martineau84084a32011-07-22 14:54:00 -07005527 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005528 break;
5529
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005530 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005531 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005532 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005533
Mat Martineau84084a32011-07-22 14:54:00 -07005534 append_skb_frag(chan->sdu, skb,
5535 &chan->sdu_last_frag);
5536 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005537
Mat Martineau84084a32011-07-22 14:54:00 -07005538 if (chan->sdu->len != chan->sdu_len)
5539 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005540
Gustavo Padovan80b98022012-05-27 22:27:51 -03005541 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005542
Mat Martineau84084a32011-07-22 14:54:00 -07005543 if (!err) {
5544 /* Reassembly complete */
5545 chan->sdu = NULL;
5546 chan->sdu_last_frag = NULL;
5547 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005548 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005549 break;
5550 }
5551
Mat Martineau84084a32011-07-22 14:54:00 -07005552 if (err) {
5553 kfree_skb(skb);
5554 kfree_skb(chan->sdu);
5555 chan->sdu = NULL;
5556 chan->sdu_last_frag = NULL;
5557 chan->sdu_len = 0;
5558 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005559
Mat Martineau84084a32011-07-22 14:54:00 -07005560 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005561}
5562
Mat Martineau32b32732012-10-23 15:24:11 -07005563static int l2cap_resegment(struct l2cap_chan *chan)
5564{
5565 /* Placeholder */
5566 return 0;
5567}
5568
Mat Martineaue3281402011-07-07 09:39:02 -07005569void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03005570{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005571 u8 event;
5572
5573 if (chan->mode != L2CAP_MODE_ERTM)
5574 return;
5575
5576 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005577 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005578}
5579
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005580static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5581{
Mat Martineau63838722012-05-17 20:53:45 -07005582 int err = 0;
5583 /* Pass sequential frames to l2cap_reassemble_sdu()
5584 * until a gap is encountered.
5585 */
5586
5587 BT_DBG("chan %p", chan);
5588
5589 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5590 struct sk_buff *skb;
5591 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5592 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5593
5594 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5595
5596 if (!skb)
5597 break;
5598
5599 skb_unlink(skb, &chan->srej_q);
5600 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5601 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5602 if (err)
5603 break;
5604 }
5605
5606 if (skb_queue_empty(&chan->srej_q)) {
5607 chan->rx_state = L2CAP_RX_STATE_RECV;
5608 l2cap_send_ack(chan);
5609 }
5610
5611 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005612}
5613
5614static void l2cap_handle_srej(struct l2cap_chan *chan,
5615 struct l2cap_ctrl *control)
5616{
Mat Martineauf80842a2012-05-17 20:53:46 -07005617 struct sk_buff *skb;
5618
5619 BT_DBG("chan %p, control %p", chan, control);
5620
5621 if (control->reqseq == chan->next_tx_seq) {
5622 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005623 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005624 return;
5625 }
5626
5627 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5628
5629 if (skb == NULL) {
5630 BT_DBG("Seq %d not available for retransmission",
5631 control->reqseq);
5632 return;
5633 }
5634
5635 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5636 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005637 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005638 return;
5639 }
5640
5641 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5642
5643 if (control->poll) {
5644 l2cap_pass_to_tx(chan, control);
5645
5646 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5647 l2cap_retransmit(chan, control);
5648 l2cap_ertm_send(chan);
5649
5650 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5651 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5652 chan->srej_save_reqseq = control->reqseq;
5653 }
5654 } else {
5655 l2cap_pass_to_tx_fbit(chan, control);
5656
5657 if (control->final) {
5658 if (chan->srej_save_reqseq != control->reqseq ||
5659 !test_and_clear_bit(CONN_SREJ_ACT,
5660 &chan->conn_state))
5661 l2cap_retransmit(chan, control);
5662 } else {
5663 l2cap_retransmit(chan, control);
5664 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5665 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5666 chan->srej_save_reqseq = control->reqseq;
5667 }
5668 }
5669 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005670}
5671
5672static void l2cap_handle_rej(struct l2cap_chan *chan,
5673 struct l2cap_ctrl *control)
5674{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005675 struct sk_buff *skb;
5676
5677 BT_DBG("chan %p, control %p", chan, control);
5678
5679 if (control->reqseq == chan->next_tx_seq) {
5680 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005681 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005682 return;
5683 }
5684
5685 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5686
5687 if (chan->max_tx && skb &&
5688 bt_cb(skb)->control.retries >= chan->max_tx) {
5689 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005690 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005691 return;
5692 }
5693
5694 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5695
5696 l2cap_pass_to_tx(chan, control);
5697
5698 if (control->final) {
5699 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5700 l2cap_retransmit_all(chan, control);
5701 } else {
5702 l2cap_retransmit_all(chan, control);
5703 l2cap_ertm_send(chan);
5704 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5705 set_bit(CONN_REJ_ACT, &chan->conn_state);
5706 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005707}
5708
Mat Martineau4b51dae92012-05-17 20:53:37 -07005709static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5710{
5711 BT_DBG("chan %p, txseq %d", chan, txseq);
5712
5713 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5714 chan->expected_tx_seq);
5715
5716 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5717 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005718 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005719 /* See notes below regarding "double poll" and
5720 * invalid packets.
5721 */
5722 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5723 BT_DBG("Invalid/Ignore - after SREJ");
5724 return L2CAP_TXSEQ_INVALID_IGNORE;
5725 } else {
5726 BT_DBG("Invalid - in window after SREJ sent");
5727 return L2CAP_TXSEQ_INVALID;
5728 }
5729 }
5730
5731 if (chan->srej_list.head == txseq) {
5732 BT_DBG("Expected SREJ");
5733 return L2CAP_TXSEQ_EXPECTED_SREJ;
5734 }
5735
5736 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5737 BT_DBG("Duplicate SREJ - txseq already stored");
5738 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5739 }
5740
5741 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5742 BT_DBG("Unexpected SREJ - not requested");
5743 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5744 }
5745 }
5746
5747 if (chan->expected_tx_seq == txseq) {
5748 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5749 chan->tx_win) {
5750 BT_DBG("Invalid - txseq outside tx window");
5751 return L2CAP_TXSEQ_INVALID;
5752 } else {
5753 BT_DBG("Expected");
5754 return L2CAP_TXSEQ_EXPECTED;
5755 }
5756 }
5757
5758 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01005759 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005760 BT_DBG("Duplicate - expected_tx_seq later than txseq");
5761 return L2CAP_TXSEQ_DUPLICATE;
5762 }
5763
5764 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
5765 /* A source of invalid packets is a "double poll" condition,
5766 * where delays cause us to send multiple poll packets. If
5767 * the remote stack receives and processes both polls,
5768 * sequence numbers can wrap around in such a way that a
5769 * resent frame has a sequence number that looks like new data
5770 * with a sequence gap. This would trigger an erroneous SREJ
5771 * request.
5772 *
5773 * Fortunately, this is impossible with a tx window that's
5774 * less than half of the maximum sequence number, which allows
5775 * invalid frames to be safely ignored.
5776 *
5777 * With tx window sizes greater than half of the tx window
5778 * maximum, the frame is invalid and cannot be ignored. This
5779 * causes a disconnect.
5780 */
5781
5782 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5783 BT_DBG("Invalid/Ignore - txseq outside tx window");
5784 return L2CAP_TXSEQ_INVALID_IGNORE;
5785 } else {
5786 BT_DBG("Invalid - txseq outside tx window");
5787 return L2CAP_TXSEQ_INVALID;
5788 }
5789 } else {
5790 BT_DBG("Unexpected - txseq indicates missing frames");
5791 return L2CAP_TXSEQ_UNEXPECTED;
5792 }
5793}
5794
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005795static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5796 struct l2cap_ctrl *control,
5797 struct sk_buff *skb, u8 event)
5798{
5799 int err = 0;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005800 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005801
5802 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5803 event);
5804
5805 switch (event) {
5806 case L2CAP_EV_RECV_IFRAME:
5807 switch (l2cap_classify_txseq(chan, control->txseq)) {
5808 case L2CAP_TXSEQ_EXPECTED:
5809 l2cap_pass_to_tx(chan, control);
5810
5811 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5812 BT_DBG("Busy, discarding expected seq %d",
5813 control->txseq);
5814 break;
5815 }
5816
5817 chan->expected_tx_seq = __next_seq(chan,
5818 control->txseq);
5819
5820 chan->buffer_seq = chan->expected_tx_seq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005821 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005822
5823 err = l2cap_reassemble_sdu(chan, skb, control);
5824 if (err)
5825 break;
5826
5827 if (control->final) {
5828 if (!test_and_clear_bit(CONN_REJ_ACT,
5829 &chan->conn_state)) {
5830 control->final = 0;
5831 l2cap_retransmit_all(chan, control);
5832 l2cap_ertm_send(chan);
5833 }
5834 }
5835
5836 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5837 l2cap_send_ack(chan);
5838 break;
5839 case L2CAP_TXSEQ_UNEXPECTED:
5840 l2cap_pass_to_tx(chan, control);
5841
5842 /* Can't issue SREJ frames in the local busy state.
5843 * Drop this frame, it will be seen as missing
5844 * when local busy is exited.
5845 */
5846 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5847 BT_DBG("Busy, discarding unexpected seq %d",
5848 control->txseq);
5849 break;
5850 }
5851
5852 /* There was a gap in the sequence, so an SREJ
5853 * must be sent for each missing frame. The
5854 * current frame is stored for later use.
5855 */
5856 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005857 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005858 BT_DBG("Queued %p (queue len %d)", skb,
5859 skb_queue_len(&chan->srej_q));
5860
5861 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5862 l2cap_seq_list_clear(&chan->srej_list);
5863 l2cap_send_srej(chan, control->txseq);
5864
5865 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5866 break;
5867 case L2CAP_TXSEQ_DUPLICATE:
5868 l2cap_pass_to_tx(chan, control);
5869 break;
5870 case L2CAP_TXSEQ_INVALID_IGNORE:
5871 break;
5872 case L2CAP_TXSEQ_INVALID:
5873 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005874 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005875 break;
5876 }
5877 break;
5878 case L2CAP_EV_RECV_RR:
5879 l2cap_pass_to_tx(chan, control);
5880 if (control->final) {
5881 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5882
Mat Martineaue6a3ee62012-10-23 15:24:22 -07005883 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
5884 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005885 control->final = 0;
5886 l2cap_retransmit_all(chan, control);
5887 }
5888
5889 l2cap_ertm_send(chan);
5890 } else if (control->poll) {
5891 l2cap_send_i_or_rr_or_rnr(chan);
5892 } else {
5893 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5894 &chan->conn_state) &&
5895 chan->unacked_frames)
5896 __set_retrans_timer(chan);
5897
5898 l2cap_ertm_send(chan);
5899 }
5900 break;
5901 case L2CAP_EV_RECV_RNR:
5902 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5903 l2cap_pass_to_tx(chan, control);
5904 if (control && control->poll) {
5905 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5906 l2cap_send_rr_or_rnr(chan, 0);
5907 }
5908 __clear_retrans_timer(chan);
5909 l2cap_seq_list_clear(&chan->retrans_list);
5910 break;
5911 case L2CAP_EV_RECV_REJ:
5912 l2cap_handle_rej(chan, control);
5913 break;
5914 case L2CAP_EV_RECV_SREJ:
5915 l2cap_handle_srej(chan, control);
5916 break;
5917 default:
5918 break;
5919 }
5920
5921 if (skb && !skb_in_use) {
5922 BT_DBG("Freeing %p", skb);
5923 kfree_skb(skb);
5924 }
5925
5926 return err;
5927}
5928
5929static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5930 struct l2cap_ctrl *control,
5931 struct sk_buff *skb, u8 event)
5932{
5933 int err = 0;
5934 u16 txseq = control->txseq;
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005935 bool skb_in_use = false;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005936
5937 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5938 event);
5939
5940 switch (event) {
5941 case L2CAP_EV_RECV_IFRAME:
5942 switch (l2cap_classify_txseq(chan, txseq)) {
5943 case L2CAP_TXSEQ_EXPECTED:
5944 /* Keep frame for reassembly later */
5945 l2cap_pass_to_tx(chan, control);
5946 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005947 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005948 BT_DBG("Queued %p (queue len %d)", skb,
5949 skb_queue_len(&chan->srej_q));
5950
5951 chan->expected_tx_seq = __next_seq(chan, txseq);
5952 break;
5953 case L2CAP_TXSEQ_EXPECTED_SREJ:
5954 l2cap_seq_list_pop(&chan->srej_list);
5955
5956 l2cap_pass_to_tx(chan, control);
5957 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005958 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005959 BT_DBG("Queued %p (queue len %d)", skb,
5960 skb_queue_len(&chan->srej_q));
5961
5962 err = l2cap_rx_queued_iframes(chan);
5963 if (err)
5964 break;
5965
5966 break;
5967 case L2CAP_TXSEQ_UNEXPECTED:
5968 /* Got a frame that can't be reassembled yet.
5969 * Save it for later, and send SREJs to cover
5970 * the missing frames.
5971 */
5972 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005973 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005974 BT_DBG("Queued %p (queue len %d)", skb,
5975 skb_queue_len(&chan->srej_q));
5976
5977 l2cap_pass_to_tx(chan, control);
5978 l2cap_send_srej(chan, control->txseq);
5979 break;
5980 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
5981 /* This frame was requested with an SREJ, but
5982 * some expected retransmitted frames are
5983 * missing. Request retransmission of missing
5984 * SREJ'd frames.
5985 */
5986 skb_queue_tail(&chan->srej_q, skb);
Peter Senna Tschudin941247f2013-09-22 20:44:10 +02005987 skb_in_use = true;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005988 BT_DBG("Queued %p (queue len %d)", skb,
5989 skb_queue_len(&chan->srej_q));
5990
5991 l2cap_pass_to_tx(chan, control);
5992 l2cap_send_srej_list(chan, control->txseq);
5993 break;
5994 case L2CAP_TXSEQ_DUPLICATE_SREJ:
5995 /* We've already queued this frame. Drop this copy. */
5996 l2cap_pass_to_tx(chan, control);
5997 break;
5998 case L2CAP_TXSEQ_DUPLICATE:
5999 /* Expecting a later sequence number, so this frame
6000 * was already received. Ignore it completely.
6001 */
6002 break;
6003 case L2CAP_TXSEQ_INVALID_IGNORE:
6004 break;
6005 case L2CAP_TXSEQ_INVALID:
6006 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006007 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006008 break;
6009 }
6010 break;
6011 case L2CAP_EV_RECV_RR:
6012 l2cap_pass_to_tx(chan, control);
6013 if (control->final) {
6014 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6015
6016 if (!test_and_clear_bit(CONN_REJ_ACT,
6017 &chan->conn_state)) {
6018 control->final = 0;
6019 l2cap_retransmit_all(chan, control);
6020 }
6021
6022 l2cap_ertm_send(chan);
6023 } else if (control->poll) {
6024 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6025 &chan->conn_state) &&
6026 chan->unacked_frames) {
6027 __set_retrans_timer(chan);
6028 }
6029
6030 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6031 l2cap_send_srej_tail(chan);
6032 } else {
6033 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6034 &chan->conn_state) &&
6035 chan->unacked_frames)
6036 __set_retrans_timer(chan);
6037
6038 l2cap_send_ack(chan);
6039 }
6040 break;
6041 case L2CAP_EV_RECV_RNR:
6042 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6043 l2cap_pass_to_tx(chan, control);
6044 if (control->poll) {
6045 l2cap_send_srej_tail(chan);
6046 } else {
6047 struct l2cap_ctrl rr_control;
6048 memset(&rr_control, 0, sizeof(rr_control));
6049 rr_control.sframe = 1;
6050 rr_control.super = L2CAP_SUPER_RR;
6051 rr_control.reqseq = chan->buffer_seq;
6052 l2cap_send_sframe(chan, &rr_control);
6053 }
6054
6055 break;
6056 case L2CAP_EV_RECV_REJ:
6057 l2cap_handle_rej(chan, control);
6058 break;
6059 case L2CAP_EV_RECV_SREJ:
6060 l2cap_handle_srej(chan, control);
6061 break;
6062 }
6063
6064 if (skb && !skb_in_use) {
6065 BT_DBG("Freeing %p", skb);
6066 kfree_skb(skb);
6067 }
6068
6069 return err;
6070}
6071
Mat Martineau32b32732012-10-23 15:24:11 -07006072static int l2cap_finish_move(struct l2cap_chan *chan)
6073{
6074 BT_DBG("chan %p", chan);
6075
6076 chan->rx_state = L2CAP_RX_STATE_RECV;
6077
6078 if (chan->hs_hcon)
6079 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6080 else
6081 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6082
6083 return l2cap_resegment(chan);
6084}
6085
6086static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6087 struct l2cap_ctrl *control,
6088 struct sk_buff *skb, u8 event)
6089{
6090 int err;
6091
6092 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6093 event);
6094
6095 if (!control->poll)
6096 return -EPROTO;
6097
6098 l2cap_process_reqseq(chan, control->reqseq);
6099
6100 if (!skb_queue_empty(&chan->tx_q))
6101 chan->tx_send_head = skb_peek(&chan->tx_q);
6102 else
6103 chan->tx_send_head = NULL;
6104
6105 /* Rewind next_tx_seq to the point expected
6106 * by the receiver.
6107 */
6108 chan->next_tx_seq = control->reqseq;
6109 chan->unacked_frames = 0;
6110
6111 err = l2cap_finish_move(chan);
6112 if (err)
6113 return err;
6114
6115 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6116 l2cap_send_i_or_rr_or_rnr(chan);
6117
6118 if (event == L2CAP_EV_RECV_IFRAME)
6119 return -EPROTO;
6120
6121 return l2cap_rx_state_recv(chan, control, NULL, event);
6122}
6123
6124static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6125 struct l2cap_ctrl *control,
6126 struct sk_buff *skb, u8 event)
6127{
6128 int err;
6129
6130 if (!control->final)
6131 return -EPROTO;
6132
6133 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6134
6135 chan->rx_state = L2CAP_RX_STATE_RECV;
6136 l2cap_process_reqseq(chan, control->reqseq);
6137
6138 if (!skb_queue_empty(&chan->tx_q))
6139 chan->tx_send_head = skb_peek(&chan->tx_q);
6140 else
6141 chan->tx_send_head = NULL;
6142
6143 /* Rewind next_tx_seq to the point expected
6144 * by the receiver.
6145 */
6146 chan->next_tx_seq = control->reqseq;
6147 chan->unacked_frames = 0;
6148
6149 if (chan->hs_hcon)
6150 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6151 else
6152 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6153
6154 err = l2cap_resegment(chan);
6155
6156 if (!err)
6157 err = l2cap_rx_state_recv(chan, control, skb, event);
6158
6159 return err;
6160}
6161
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006162static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6163{
6164 /* Make sure reqseq is for a packet that has been sent but not acked */
6165 u16 unacked;
6166
6167 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6168 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6169}
6170
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006171static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6172 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006173{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006174 int err = 0;
6175
6176 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6177 control, skb, event, chan->rx_state);
6178
6179 if (__valid_reqseq(chan, control->reqseq)) {
6180 switch (chan->rx_state) {
6181 case L2CAP_RX_STATE_RECV:
6182 err = l2cap_rx_state_recv(chan, control, skb, event);
6183 break;
6184 case L2CAP_RX_STATE_SREJ_SENT:
6185 err = l2cap_rx_state_srej_sent(chan, control, skb,
6186 event);
6187 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006188 case L2CAP_RX_STATE_WAIT_P:
6189 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6190 break;
6191 case L2CAP_RX_STATE_WAIT_F:
6192 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6193 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006194 default:
6195 /* shut it down */
6196 break;
6197 }
6198 } else {
6199 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6200 control->reqseq, chan->next_tx_seq,
6201 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006202 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006203 }
6204
6205 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006206}
6207
6208static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6209 struct sk_buff *skb)
6210{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006211 int err = 0;
6212
6213 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6214 chan->rx_state);
6215
6216 if (l2cap_classify_txseq(chan, control->txseq) ==
6217 L2CAP_TXSEQ_EXPECTED) {
6218 l2cap_pass_to_tx(chan, control);
6219
6220 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6221 __next_seq(chan, chan->buffer_seq));
6222
6223 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6224
6225 l2cap_reassemble_sdu(chan, skb, control);
6226 } else {
6227 if (chan->sdu) {
6228 kfree_skb(chan->sdu);
6229 chan->sdu = NULL;
6230 }
6231 chan->sdu_last_frag = NULL;
6232 chan->sdu_len = 0;
6233
6234 if (skb) {
6235 BT_DBG("Freeing %p", skb);
6236 kfree_skb(skb);
6237 }
6238 }
6239
6240 chan->last_acked_seq = control->txseq;
6241 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6242
6243 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006244}
6245
6246static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6247{
6248 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6249 u16 len;
6250 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006251
Mat Martineaub76bbd62012-04-11 10:48:43 -07006252 __unpack_control(chan, skb);
6253
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006254 len = skb->len;
6255
6256 /*
6257 * We can just drop the corrupted I-frame here.
6258 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006259 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006260 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006261 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006262 goto drop;
6263
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006264 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006265 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006266
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006267 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006268 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006269
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006270 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006271 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006272 goto drop;
6273 }
6274
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006275 if (!control->sframe) {
6276 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006277
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006278 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6279 control->sar, control->reqseq, control->final,
6280 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006281
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006282 /* Validate F-bit - F=0 always valid, F=1 only
6283 * valid in TX WAIT_F
6284 */
6285 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006286 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006287
6288 if (chan->mode != L2CAP_MODE_STREAMING) {
6289 event = L2CAP_EV_RECV_IFRAME;
6290 err = l2cap_rx(chan, control, skb, event);
6291 } else {
6292 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006293 }
6294
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006295 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006296 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006297 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006298 const u8 rx_func_to_event[4] = {
6299 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6300 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6301 };
6302
6303 /* Only I-frames are expected in streaming mode */
6304 if (chan->mode == L2CAP_MODE_STREAMING)
6305 goto drop;
6306
6307 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6308 control->reqseq, control->final, control->poll,
6309 control->super);
6310
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006311 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006312 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006313 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006314 goto drop;
6315 }
6316
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006317 /* Validate F and P bits */
6318 if (control->final && (control->poll ||
6319 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6320 goto drop;
6321
6322 event = rx_func_to_event[control->super];
6323 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006324 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006325 }
6326
6327 return 0;
6328
6329drop:
6330 kfree_skb(skb);
6331 return 0;
6332}
6333
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006334static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6335 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006336{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006337 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006338
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006339 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006340 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006341 if (cid == L2CAP_CID_A2MP) {
6342 chan = a2mp_channel_create(conn, skb);
6343 if (!chan) {
6344 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006345 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006346 }
6347
6348 l2cap_chan_lock(chan);
6349 } else {
6350 BT_DBG("unknown cid 0x%4.4x", cid);
6351 /* Drop packet and return */
6352 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006353 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006354 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006355 }
6356
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006357 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006358
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006359 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006360 goto drop;
6361
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006362 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006363 case L2CAP_MODE_BASIC:
6364 /* If socket recv buffers overflows we drop data here
6365 * which is *bad* because L2CAP has to be reliable.
6366 * But we don't have any other choice. L2CAP doesn't
6367 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006368
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006369 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006370 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006371
Gustavo Padovan80b98022012-05-27 22:27:51 -03006372 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006373 goto done;
6374 break;
6375
6376 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006377 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006378 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006379 goto done;
6380
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006381 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006382 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006383 break;
6384 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006385
6386drop:
6387 kfree_skb(skb);
6388
6389done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006390 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006391}
6392
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006393static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6394 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006395{
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006396 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006397 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006398
Marcel Holtmannae4fd2d2013-10-03 00:03:39 -07006399 if (hcon->type != ACL_LINK)
6400 goto drop;
6401
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006402 chan = l2cap_global_chan_by_psm(0, psm, &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006403 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006404 goto drop;
6405
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006406 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006407
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006408 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006409 goto drop;
6410
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006411 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006412 goto drop;
6413
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006414 /* Store remote BD_ADDR and PSM for msg_name */
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006415 bacpy(&bt_cb(skb)->bdaddr, &hcon->dst);
Marcel Holtmann2edf8702013-10-13 12:55:29 -07006416 bt_cb(skb)->psm = psm;
6417
Gustavo Padovan80b98022012-05-27 22:27:51 -03006418 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006419 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006420
6421drop:
6422 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006423}
6424
Marcel Holtmann72f78352013-04-23 00:59:00 -07006425static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006426 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006427{
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006428 struct hci_conn *hcon = conn->hcon;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006429 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006430
Marcel Holtmannb99707d2013-10-03 02:54:11 -07006431 if (hcon->type != LE_LINK)
6432 goto drop;
6433
Johan Hedbergaf1c0132013-04-29 19:35:42 +03006434 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann06ae3312013-10-18 03:43:00 -07006435 &hcon->src, &hcon->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006436 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006437 goto drop;
6438
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006439 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006440
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006441 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006442 goto drop;
6443
Gustavo Padovan80b98022012-05-27 22:27:51 -03006444 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006445 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006446
6447drop:
6448 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006449}
6450
Linus Torvalds1da177e2005-04-16 15:20:36 -07006451static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6452{
6453 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006454 u16 cid, len;
6455 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006456
6457 skb_pull(skb, L2CAP_HDR_SIZE);
6458 cid = __le16_to_cpu(lh->cid);
6459 len = __le16_to_cpu(lh->len);
6460
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006461 if (len != skb->len) {
6462 kfree_skb(skb);
6463 return;
6464 }
6465
Linus Torvalds1da177e2005-04-16 15:20:36 -07006466 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6467
6468 switch (cid) {
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006469 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006470 l2cap_sig_channel(conn, skb);
6471 break;
6472
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006473 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006474 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006475 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006476 l2cap_conless_channel(conn, psm, skb);
6477 break;
6478
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006479 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006480 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006481 break;
6482
Marcel Holtmanna2877622013-10-02 23:46:54 -07006483 case L2CAP_CID_LE_SIGNALING:
6484 l2cap_le_sig_channel(conn, skb);
6485 break;
6486
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006487 case L2CAP_CID_SMP:
6488 if (smp_sig_channel(conn, skb))
6489 l2cap_conn_del(conn->hcon, EACCES);
6490 break;
6491
Linus Torvalds1da177e2005-04-16 15:20:36 -07006492 default:
6493 l2cap_data_channel(conn, cid, skb);
6494 break;
6495 }
6496}
6497
6498/* ---- L2CAP interface with lower layer (HCI) ---- */
6499
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006500int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006501{
6502 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006503 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006504
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006505 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006506
6507 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006508 read_lock(&chan_list_lock);
6509 list_for_each_entry(c, &chan_list, global_l) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006510 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006511 continue;
6512
Marcel Holtmann7eafc592013-10-13 08:12:47 -07006513 if (!bacmp(&c->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006514 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006515 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006516 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006517 exact++;
Marcel Holtmann7eafc592013-10-13 08:12:47 -07006518 } else if (!bacmp(&c->src, BDADDR_ANY)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006519 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006520 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006521 lm2 |= HCI_LM_MASTER;
6522 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006523 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006524 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006525
6526 return exact ? lm1 : lm2;
6527}
6528
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006529void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006530{
Marcel Holtmann01394182006-07-03 10:02:46 +02006531 struct l2cap_conn *conn;
6532
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006533 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006534
Linus Torvalds1da177e2005-04-16 15:20:36 -07006535 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03006536 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006537 if (conn)
6538 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006539 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006540 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006541 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006542}
6543
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006544int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006545{
6546 struct l2cap_conn *conn = hcon->l2cap_data;
6547
6548 BT_DBG("hcon %p", hcon);
6549
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006550 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006551 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006552 return conn->disc_reason;
6553}
6554
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006555void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006556{
6557 BT_DBG("hcon %p reason %d", hcon, reason);
6558
Joe Perchese1750722011-06-29 18:18:29 -07006559 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006560}
6561
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006562static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006563{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006564 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006565 return;
6566
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006567 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006568 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006569 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006570 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006571 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006572 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006573 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006574 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006575 }
6576}
6577
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006578int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006579{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006580 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006581 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006582
Marcel Holtmann01394182006-07-03 10:02:46 +02006583 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006584 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006585
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006586 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006587
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006588 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306589 if (!status && encrypt)
6590 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006591 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006592 }
6593
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006594 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006595
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006596 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006597 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006598
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006599 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6600 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006601
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006602 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6603 l2cap_chan_unlock(chan);
6604 continue;
6605 }
6606
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006607 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006608 if (!status && encrypt) {
6609 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006610 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006611 }
6612
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006613 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006614 continue;
6615 }
6616
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006617 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006618 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006619 continue;
6620 }
6621
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006622 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006623 chan->state == BT_CONFIG)) {
Marcel Holtmannd97c8992013-10-14 02:53:54 -07006624 chan->ops->resume(chan);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006625 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006626 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006627 continue;
6628 }
6629
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006630 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006631 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006632 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006633 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006634 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006635 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006636 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006637 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006638 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006639 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006640
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006641 lock_sock(sk);
6642
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006643 if (!status) {
Marcel Holtmannbdc25782013-10-14 02:45:34 -07006644 if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006645 res = L2CAP_CR_PEND;
6646 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006647 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006648 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006649 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006650 res = L2CAP_CR_SUCCESS;
6651 stat = L2CAP_CS_NO_INFO;
6652 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006653 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006654 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006655 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006656 res = L2CAP_CR_SEC_BLOCK;
6657 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006658 }
6659
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006660 release_sock(sk);
6661
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006662 rsp.scid = cpu_to_le16(chan->dcid);
6663 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006664 rsp.result = cpu_to_le16(res);
6665 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006666 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006667 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006668
6669 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6670 res == L2CAP_CR_SUCCESS) {
6671 char buf[128];
6672 set_bit(CONF_REQ_SENT, &chan->conf_state);
6673 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6674 L2CAP_CONF_REQ,
6675 l2cap_build_conf_req(chan, buf),
6676 buf);
6677 chan->num_conf_req++;
6678 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006679 }
6680
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006681 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006682 }
6683
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006684 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006685
Linus Torvalds1da177e2005-04-16 15:20:36 -07006686 return 0;
6687}
6688
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006689int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006690{
6691 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006692 struct l2cap_hdr *hdr;
6693 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006694
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006695 /* For AMP controller do not create l2cap conn */
6696 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6697 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006698
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006699 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03006700 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006701
6702 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006703 goto drop;
6704
6705 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6706
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006707 switch (flags) {
6708 case ACL_START:
6709 case ACL_START_NO_FLUSH:
6710 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006711 if (conn->rx_len) {
6712 BT_ERR("Unexpected start frame (len %d)", skb->len);
6713 kfree_skb(conn->rx_skb);
6714 conn->rx_skb = NULL;
6715 conn->rx_len = 0;
6716 l2cap_conn_unreliable(conn, ECOMM);
6717 }
6718
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006719 /* Start fragment always begin with Basic L2CAP header */
6720 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006721 BT_ERR("Frame is too short (len %d)", skb->len);
6722 l2cap_conn_unreliable(conn, ECOMM);
6723 goto drop;
6724 }
6725
6726 hdr = (struct l2cap_hdr *) skb->data;
6727 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6728
6729 if (len == skb->len) {
6730 /* Complete frame received */
6731 l2cap_recv_frame(conn, skb);
6732 return 0;
6733 }
6734
6735 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6736
6737 if (skb->len > len) {
6738 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006739 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006740 l2cap_conn_unreliable(conn, ECOMM);
6741 goto drop;
6742 }
6743
6744 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006745 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006746 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006747 goto drop;
6748
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006749 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006750 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006751 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006752 break;
6753
6754 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006755 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6756
6757 if (!conn->rx_len) {
6758 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6759 l2cap_conn_unreliable(conn, ECOMM);
6760 goto drop;
6761 }
6762
6763 if (skb->len > conn->rx_len) {
6764 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006765 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006766 kfree_skb(conn->rx_skb);
6767 conn->rx_skb = NULL;
6768 conn->rx_len = 0;
6769 l2cap_conn_unreliable(conn, ECOMM);
6770 goto drop;
6771 }
6772
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006773 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006774 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006775 conn->rx_len -= skb->len;
6776
6777 if (!conn->rx_len) {
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02006778 /* Complete frame received. l2cap_recv_frame
6779 * takes ownership of the skb so set the global
6780 * rx_skb pointer to NULL first.
6781 */
6782 struct sk_buff *rx_skb = conn->rx_skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006783 conn->rx_skb = NULL;
Johan Hedbergc4e5baf2013-10-10 13:33:37 +02006784 l2cap_recv_frame(conn, rx_skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006785 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006786 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006787 }
6788
6789drop:
6790 kfree_skb(skb);
6791 return 0;
6792}
6793
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006794static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006795{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006796 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006797
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006798 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006799
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006800 list_for_each_entry(c, &chan_list, global_l) {
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006801 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 -07006802 &c->src, &c->dst,
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006803 c->state, __le16_to_cpu(c->psm),
6804 c->scid, c->dcid, c->imtu, c->omtu,
6805 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006806 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006807
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006808 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006809
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006810 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006811}
6812
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006813static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6814{
6815 return single_open(file, l2cap_debugfs_show, inode->i_private);
6816}
6817
6818static const struct file_operations l2cap_debugfs_fops = {
6819 .open = l2cap_debugfs_open,
6820 .read = seq_read,
6821 .llseek = seq_lseek,
6822 .release = single_release,
6823};
6824
6825static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006826
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006827int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006828{
6829 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006830
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006831 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006832 if (err < 0)
6833 return err;
6834
Marcel Holtmann1120e4b2013-10-17 17:24:16 -07006835 if (IS_ERR_OR_NULL(bt_debugfs))
6836 return 0;
6837
6838 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6839 NULL, &l2cap_debugfs_fops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006840
Linus Torvalds1da177e2005-04-16 15:20:36 -07006841 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006842}
6843
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006844void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006845{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006846 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006847 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006848}
6849
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006850module_param(disable_ertm, bool, 0644);
6851MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");