blob: be9ad89339cd513f1f556072044e095f332c7b78 [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>
Anderson Brigliab501d6a2011-06-07 18:46:31 -030039#include <net/bluetooth/smp.h>
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +030040#include <net/bluetooth/a2mp.h>
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +020041#include <net/bluetooth/amp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
Mat Martineaud1de6d42012-05-17 20:53:55 -070043bool disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020044
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070045static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Mat Martineau50a147c2011-11-02 16:18:34 -070046static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070047
Johannes Bergb5ad8b72011-06-01 08:54:45 +020048static LIST_HEAD(chan_list);
49static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
Linus Torvalds1da177e2005-04-16 15:20:36 -070051static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +010052 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030053static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
Gustavo Padovan2d792812012-10-06 10:07:01 +010054 void *data);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -030055static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +020056static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Gustavo Padovand6603662012-05-21 13:58:22 -030058static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
Gustavo Padovan2d792812012-10-06 10:07:01 +010059 struct sk_buff_head *skbs, u8 event);
Mat Martineau608bcc62012-05-17 20:53:32 -070060
Marcel Holtmann01394182006-07-03 10:02:46 +020061/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030062
Gustavo Padovan2d792812012-10-06 10:07:01 +010063static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
64 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020065{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020066 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030067
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020068 list_for_each_entry(c, &conn->chan_l, list) {
69 if (c->dcid == cid)
70 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020071 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020072 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020073}
74
Gustavo Padovan2d792812012-10-06 10:07:01 +010075static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
76 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020077{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020078 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030079
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020080 list_for_each_entry(c, &conn->chan_l, list) {
81 if (c->scid == cid)
82 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020083 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020084 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020085}
86
87/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -070088 * Returns locked channel. */
Gustavo Padovan2d792812012-10-06 10:07:01 +010089static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
90 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020091{
Gustavo F. Padovan48454072011-03-25 00:22:30 -030092 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030093
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020094 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030095 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -070096 if (c)
97 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020098 mutex_unlock(&conn->chan_lock);
99
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300100 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200101}
102
Mat Martineaub1a130b2012-10-23 15:24:09 -0700103/* Find channel with given DCID.
104 * Returns locked channel.
105 */
106static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
107 u16 cid)
108{
109 struct l2cap_chan *c;
110
111 mutex_lock(&conn->chan_lock);
112 c = __l2cap_get_chan_by_dcid(conn, cid);
113 if (c)
114 l2cap_chan_lock(c);
115 mutex_unlock(&conn->chan_lock);
116
117 return c;
118}
119
Gustavo Padovan2d792812012-10-06 10:07:01 +0100120static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
121 u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200122{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200123 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300124
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200125 list_for_each_entry(c, &conn->chan_l, list) {
126 if (c->ident == ident)
127 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200128 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200129 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200130}
131
Mat Martineau5b155ef2012-10-23 15:24:14 -0700132static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
133 u8 ident)
134{
135 struct l2cap_chan *c;
136
137 mutex_lock(&conn->chan_lock);
138 c = __l2cap_get_chan_by_ident(conn, ident);
139 if (c)
140 l2cap_chan_lock(c);
141 mutex_unlock(&conn->chan_lock);
142
143 return c;
144}
145
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300146static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300147{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300148 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300149
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300150 list_for_each_entry(c, &chan_list, global_l) {
151 if (c->sport == psm && !bacmp(&bt_sk(c->sk)->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100152 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300153 }
Szymon Janc250938c2011-11-16 09:32:22 +0100154 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300155}
156
157int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
158{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300159 int err;
160
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200161 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300162
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300163 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300164 err = -EADDRINUSE;
165 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300166 }
167
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300168 if (psm) {
169 chan->psm = psm;
170 chan->sport = psm;
171 err = 0;
172 } else {
173 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300174
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300175 err = -EINVAL;
176 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300177 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300178 chan->psm = cpu_to_le16(p);
179 chan->sport = cpu_to_le16(p);
180 err = 0;
181 break;
182 }
183 }
184
185done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200186 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300187 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300188}
189
190int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
191{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200192 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300193
194 chan->scid = scid;
195
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200196 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300197
198 return 0;
199}
200
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300201static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200202{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300203 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200204
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300205 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300206 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200207 return cid;
208 }
209
210 return 0;
211}
212
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200213static void __l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300214{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200215 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100216 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200217
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300218 chan->state = state;
Gustavo Padovan80b98022012-05-27 22:27:51 -0300219 chan->ops->state_change(chan, state);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300220}
221
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200222static void l2cap_state_change(struct l2cap_chan *chan, int state)
223{
224 struct sock *sk = chan->sk;
225
226 lock_sock(sk);
227 __l2cap_state_change(chan, state);
228 release_sock(sk);
229}
230
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200231static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err)
232{
233 struct sock *sk = chan->sk;
234
235 sk->sk_err = err;
236}
237
238static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
239{
240 struct sock *sk = chan->sk;
241
242 lock_sock(sk);
243 __l2cap_chan_set_err(chan, err);
244 release_sock(sk);
245}
246
Mat Martineau4239d162012-05-17 20:53:49 -0700247static void __set_retrans_timer(struct l2cap_chan *chan)
248{
249 if (!delayed_work_pending(&chan->monitor_timer) &&
250 chan->retrans_timeout) {
251 l2cap_set_timer(chan, &chan->retrans_timer,
252 msecs_to_jiffies(chan->retrans_timeout));
253 }
254}
255
256static void __set_monitor_timer(struct l2cap_chan *chan)
257{
258 __clear_retrans_timer(chan);
259 if (chan->monitor_timeout) {
260 l2cap_set_timer(chan, &chan->monitor_timer,
261 msecs_to_jiffies(chan->monitor_timeout));
262 }
263}
264
Mat Martineau608bcc62012-05-17 20:53:32 -0700265static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
266 u16 seq)
267{
268 struct sk_buff *skb;
269
270 skb_queue_walk(head, skb) {
271 if (bt_cb(skb)->control.txseq == seq)
272 return skb;
273 }
274
275 return NULL;
276}
277
Mat Martineau3c588192012-04-11 10:48:42 -0700278/* ---- L2CAP sequence number lists ---- */
279
280/* For ERTM, ordered lists of sequence numbers must be tracked for
281 * SREJ requests that are received and for frames that are to be
282 * retransmitted. These seq_list functions implement a singly-linked
283 * list in an array, where membership in the list can also be checked
284 * in constant time. Items can also be added to the tail of the list
285 * and removed from the head in constant time, without further memory
286 * allocs or frees.
287 */
288
289static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
290{
291 size_t alloc_size, i;
292
293 /* Allocated size is a power of 2 to map sequence numbers
294 * (which may be up to 14 bits) in to a smaller array that is
295 * sized for the negotiated ERTM transmit windows.
296 */
297 alloc_size = roundup_pow_of_two(size);
298
299 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
300 if (!seq_list->list)
301 return -ENOMEM;
302
303 seq_list->mask = alloc_size - 1;
304 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
305 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
306 for (i = 0; i < alloc_size; i++)
307 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
308
309 return 0;
310}
311
312static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
313{
314 kfree(seq_list->list);
315}
316
317static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
318 u16 seq)
319{
320 /* Constant-time check for list membership */
321 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
322}
323
324static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
325{
326 u16 mask = seq_list->mask;
327
328 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
329 /* In case someone tries to pop the head of an empty list */
330 return L2CAP_SEQ_LIST_CLEAR;
331 } else if (seq_list->head == seq) {
332 /* Head can be removed in constant time */
333 seq_list->head = seq_list->list[seq & mask];
334 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
335
336 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
337 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
338 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
339 }
340 } else {
341 /* Walk the list to find the sequence number */
342 u16 prev = seq_list->head;
343 while (seq_list->list[prev & mask] != seq) {
344 prev = seq_list->list[prev & mask];
345 if (prev == L2CAP_SEQ_LIST_TAIL)
346 return L2CAP_SEQ_LIST_CLEAR;
347 }
348
349 /* Unlink the number from the list and clear it */
350 seq_list->list[prev & mask] = seq_list->list[seq & mask];
351 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
352 if (seq_list->tail == seq)
353 seq_list->tail = prev;
354 }
355 return seq;
356}
357
358static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
359{
360 /* Remove the head in constant time */
361 return l2cap_seq_list_remove(seq_list, seq_list->head);
362}
363
364static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
365{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300366 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700367
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300368 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
369 return;
370
371 for (i = 0; i <= seq_list->mask; i++)
372 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
373
374 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
375 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700376}
377
378static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
379{
380 u16 mask = seq_list->mask;
381
382 /* All appends happen in constant time */
383
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300384 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
385 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700386
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300387 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
388 seq_list->head = seq;
389 else
390 seq_list->list[seq_list->tail & mask] = seq;
391
392 seq_list->tail = seq;
393 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700394}
395
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300396static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300397{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300398 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100399 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200400 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300401 int reason;
402
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200403 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300404
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200405 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200406 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300407
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300408 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300409 reason = ECONNREFUSED;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300410 else if (chan->state == BT_CONNECT &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100411 chan->sec_level != BT_SECURITY_SDP)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300412 reason = ECONNREFUSED;
413 else
414 reason = ETIMEDOUT;
415
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300416 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300417
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200418 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300419
Gustavo Padovan80b98022012-05-27 22:27:51 -0300420 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200421 mutex_unlock(&conn->chan_lock);
422
Ulisses Furquim371fd832011-12-21 20:02:36 -0200423 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300424}
425
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300426struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200427{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300428 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200429
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300430 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
431 if (!chan)
432 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200433
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200434 mutex_init(&chan->lock);
435
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200436 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300437 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200438 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300439
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300440 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300441
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300442 chan->state = BT_OPEN;
443
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530444 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300445
Mat Martineau28270112012-05-17 21:14:09 -0700446 /* This flag is cleared in l2cap_chan_ready() */
447 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
448
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300449 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100450
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300451 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200452}
453
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530454static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300455{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530456 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
457
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530458 BT_DBG("chan %p", chan);
459
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200460 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300461 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200462 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300463
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530464 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300465}
466
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530467void l2cap_chan_hold(struct l2cap_chan *c)
468{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530469 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530470
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530471 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530472}
473
474void l2cap_chan_put(struct l2cap_chan *c)
475{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530476 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530477
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530478 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530479}
480
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300481void l2cap_chan_set_defaults(struct l2cap_chan *chan)
482{
483 chan->fcs = L2CAP_FCS_CRC16;
484 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
485 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
486 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700487 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300488 chan->sec_level = BT_SECURITY_LOW;
489
490 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
491}
492
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300493void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200494{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300495 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200496 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200497
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200498 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100499
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300500 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200501
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200502 switch (chan->chan_type) {
503 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300504 if (conn->hcon->type == LE_LINK) {
505 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300506 chan->omtu = L2CAP_DEFAULT_MTU;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300507 chan->scid = L2CAP_CID_LE_DATA;
508 chan->dcid = L2CAP_CID_LE_DATA;
Ville Tervob62f3282011-02-10 22:38:50 -0300509 } else {
510 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300511 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300512 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300513 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200514 break;
515
516 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200517 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300518 chan->scid = L2CAP_CID_CONN_LESS;
519 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300520 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200521 break;
522
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300523 case L2CAP_CHAN_CONN_FIX_A2MP:
524 chan->scid = L2CAP_CID_A2MP;
525 chan->dcid = L2CAP_CID_A2MP;
526 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
527 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
528 break;
529
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200530 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200531 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300532 chan->scid = L2CAP_CID_SIGNALING;
533 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300534 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200535 }
536
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300537 chan->local_id = L2CAP_BESTEFFORT_ID;
538 chan->local_stype = L2CAP_SERV_BESTEFFORT;
539 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
540 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
541 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300542 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300543
Ulisses Furquim371fd832011-12-21 20:02:36 -0200544 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300545
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200546 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200547}
548
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300549void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200550{
551 mutex_lock(&conn->chan_lock);
552 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200553 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200554}
555
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300556void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200557{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300558 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200559
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300560 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200561
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300562 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200563
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900564 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300565 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300566 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200567 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200568
Ulisses Furquim371fd832011-12-21 20:02:36 -0200569 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300570
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300571 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300572
573 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
David Herrmann76a68ba2013-04-06 20:28:37 +0200574 hci_conn_drop(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300575
576 if (mgr && mgr->bredr_chan == chan)
577 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200578 }
579
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200580 if (chan->hs_hchan) {
581 struct hci_chan *hs_hchan = chan->hs_hchan;
582
583 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
584 amp_disconnect_logical_link(hs_hchan);
585 }
586
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100587 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200588
Mat Martineau28270112012-05-17 21:14:09 -0700589 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300590 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300591
Gustavo Padovanee556f62012-05-18 20:22:38 -0300592 switch(chan->mode) {
593 case L2CAP_MODE_BASIC:
594 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300595
Gustavo Padovanee556f62012-05-18 20:22:38 -0300596 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300597 __clear_retrans_timer(chan);
598 __clear_monitor_timer(chan);
599 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300600
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300601 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300602
Mat Martineau3c588192012-04-11 10:48:42 -0700603 l2cap_seq_list_free(&chan->srej_list);
604 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300605
606 /* fall through */
607
608 case L2CAP_MODE_STREAMING:
609 skb_queue_purge(&chan->tx_q);
610 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300611 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300612
613 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200614}
615
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300616void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300617{
618 struct l2cap_conn *conn = chan->conn;
619 struct sock *sk = chan->sk;
620
Gustavo Padovan2d792812012-10-06 10:07:01 +0100621 BT_DBG("chan %p state %s sk %p", chan, state_to_string(chan->state),
622 sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300623
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300624 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300625 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100626 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300627 break;
628
629 case BT_CONNECTED:
630 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300631 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100632 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300633 __set_chan_timer(chan, sk->sk_sndtimeo);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200634 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300635 } else
636 l2cap_chan_del(chan, reason);
637 break;
638
639 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300640 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100641 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300642 struct l2cap_conn_rsp rsp;
643 __u16 result;
644
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300645 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300646 result = L2CAP_CR_SEC_BLOCK;
647 else
648 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300649 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300650
651 rsp.scid = cpu_to_le16(chan->dcid);
652 rsp.dcid = cpu_to_le16(chan->scid);
653 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300654 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300655 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100656 sizeof(rsp), &rsp);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300657 }
658
659 l2cap_chan_del(chan, reason);
660 break;
661
662 case BT_CONNECT:
663 case BT_DISCONN:
664 l2cap_chan_del(chan, reason);
665 break;
666
667 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100668 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300669 break;
670 }
671}
672
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300673static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530674{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300675 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300676 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530677 case BT_SECURITY_HIGH:
678 return HCI_AT_DEDICATED_BONDING_MITM;
679 case BT_SECURITY_MEDIUM:
680 return HCI_AT_DEDICATED_BONDING;
681 default:
682 return HCI_AT_NO_BONDING;
683 }
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +0300684 } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300685 if (chan->sec_level == BT_SECURITY_LOW)
686 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530687
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300688 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530689 return HCI_AT_NO_BONDING_MITM;
690 else
691 return HCI_AT_NO_BONDING;
692 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300693 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530694 case BT_SECURITY_HIGH:
695 return HCI_AT_GENERAL_BONDING_MITM;
696 case BT_SECURITY_MEDIUM:
697 return HCI_AT_GENERAL_BONDING;
698 default:
699 return HCI_AT_NO_BONDING;
700 }
701 }
702}
703
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200704/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200705int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200706{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300707 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100708 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200709
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300710 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100711
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300712 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200713}
714
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200715static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200716{
717 u8 id;
718
719 /* Get next available identificator.
720 * 1 - 128 are used by kernel.
721 * 129 - 199 are reserved.
722 * 200 - 254 are used by utilities like l2ping, etc.
723 */
724
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200725 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200726
727 if (++conn->tx_ident > 128)
728 conn->tx_ident = 1;
729
730 id = conn->tx_ident;
731
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200732 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200733
734 return id;
735}
736
Gustavo Padovan2d792812012-10-06 10:07:01 +0100737static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
738 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200739{
740 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200741 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200742
743 BT_DBG("code 0x%2.2x", code);
744
745 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300746 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200747
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200748 if (lmp_no_flush_capable(conn->hcon->hdev))
749 flags = ACL_START_NO_FLUSH;
750 else
751 flags = ACL_START;
752
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700753 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200754 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700755
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200756 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200757}
758
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700759static bool __chan_is_moving(struct l2cap_chan *chan)
760{
761 return chan->move_state != L2CAP_MOVE_STABLE &&
762 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
763}
764
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200765static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
766{
767 struct hci_conn *hcon = chan->conn->hcon;
768 u16 flags;
769
770 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100771 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200772
Mat Martineaud5f8a752012-10-23 15:24:18 -0700773 if (chan->hs_hcon && !__chan_is_moving(chan)) {
774 if (chan->hs_hchan)
775 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
776 else
777 kfree_skb(skb);
778
779 return;
780 }
781
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200782 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100783 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200784 flags = ACL_START_NO_FLUSH;
785 else
786 flags = ACL_START;
787
788 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
789 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790}
791
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700792static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
793{
794 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
795 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
796
797 if (enh & L2CAP_CTRL_FRAME_TYPE) {
798 /* S-Frame */
799 control->sframe = 1;
800 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
801 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
802
803 control->sar = 0;
804 control->txseq = 0;
805 } else {
806 /* I-Frame */
807 control->sframe = 0;
808 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
809 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
810
811 control->poll = 0;
812 control->super = 0;
813 }
814}
815
816static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
817{
818 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
819 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
820
821 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
822 /* S-Frame */
823 control->sframe = 1;
824 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
825 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
826
827 control->sar = 0;
828 control->txseq = 0;
829 } else {
830 /* I-Frame */
831 control->sframe = 0;
832 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
833 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
834
835 control->poll = 0;
836 control->super = 0;
837 }
838}
839
840static inline void __unpack_control(struct l2cap_chan *chan,
841 struct sk_buff *skb)
842{
843 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
844 __unpack_extended_control(get_unaligned_le32(skb->data),
845 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700846 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700847 } else {
848 __unpack_enhanced_control(get_unaligned_le16(skb->data),
849 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700850 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700851 }
852}
853
854static u32 __pack_extended_control(struct l2cap_ctrl *control)
855{
856 u32 packed;
857
858 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
859 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
860
861 if (control->sframe) {
862 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
863 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
864 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
865 } else {
866 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
867 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
868 }
869
870 return packed;
871}
872
873static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
874{
875 u16 packed;
876
877 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
878 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
879
880 if (control->sframe) {
881 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
882 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
883 packed |= L2CAP_CTRL_FRAME_TYPE;
884 } else {
885 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
886 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
887 }
888
889 return packed;
890}
891
892static inline void __pack_control(struct l2cap_chan *chan,
893 struct l2cap_ctrl *control,
894 struct sk_buff *skb)
895{
896 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
897 put_unaligned_le32(__pack_extended_control(control),
898 skb->data + L2CAP_HDR_SIZE);
899 } else {
900 put_unaligned_le16(__pack_enhanced_control(control),
901 skb->data + L2CAP_HDR_SIZE);
902 }
903}
904
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300905static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
906{
907 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
908 return L2CAP_EXT_HDR_SIZE;
909 else
910 return L2CAP_ENH_HDR_SIZE;
911}
912
Mat Martineaua67d7f62012-05-17 20:53:35 -0700913static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
914 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300915{
916 struct sk_buff *skb;
917 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300918 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300919
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300920 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300921 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300922
Mat Martineaua67d7f62012-05-17 20:53:35 -0700923 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300924
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300925 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700926 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300927
928 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300929 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300930 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300931
Mat Martineaua67d7f62012-05-17 20:53:35 -0700932 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
933 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
934 else
935 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300936
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300937 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700938 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300939 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300940 }
941
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200942 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700943 return skb;
944}
945
946static void l2cap_send_sframe(struct l2cap_chan *chan,
947 struct l2cap_ctrl *control)
948{
949 struct sk_buff *skb;
950 u32 control_field;
951
952 BT_DBG("chan %p, control %p", chan, control);
953
954 if (!control->sframe)
955 return;
956
Mat Martineaub99e13a2012-10-23 15:24:19 -0700957 if (__chan_is_moving(chan))
958 return;
959
Mat Martineaua67d7f62012-05-17 20:53:35 -0700960 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
961 !control->poll)
962 control->final = 1;
963
964 if (control->super == L2CAP_SUPER_RR)
965 clear_bit(CONN_RNR_SENT, &chan->conn_state);
966 else if (control->super == L2CAP_SUPER_RNR)
967 set_bit(CONN_RNR_SENT, &chan->conn_state);
968
969 if (control->super != L2CAP_SUPER_SREJ) {
970 chan->last_acked_seq = control->reqseq;
971 __clear_ack_timer(chan);
972 }
973
974 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
975 control->final, control->poll, control->super);
976
977 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
978 control_field = __pack_extended_control(control);
979 else
980 control_field = __pack_enhanced_control(control);
981
982 skb = l2cap_create_sframe_pdu(chan, control_field);
983 if (!IS_ERR(skb))
984 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300985}
986
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700987static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300988{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700989 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300990
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700991 BT_DBG("chan %p, poll %d", chan, poll);
992
993 memset(&control, 0, sizeof(control));
994 control.sframe = 1;
995 control.poll = poll;
996
997 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
998 control.super = L2CAP_SUPER_RNR;
999 else
1000 control.super = L2CAP_SUPER_RR;
1001
1002 control.reqseq = chan->buffer_seq;
1003 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001004}
1005
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001006static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001007{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001008 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001009}
1010
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001011static bool __amp_capable(struct l2cap_chan *chan)
1012{
1013 struct l2cap_conn *conn = chan->conn;
1014
1015 if (enable_hs &&
Andrei Emeltchenko5d054162012-11-29 17:46:05 +02001016 hci_amp_capable() &&
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001017 chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED &&
1018 conn->fixed_chan_mask & L2CAP_FC_A2MP)
1019 return true;
1020 else
1021 return false;
1022}
1023
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001024static bool l2cap_check_efs(struct l2cap_chan *chan)
1025{
1026 /* Check EFS parameters */
1027 return true;
1028}
1029
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001030void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001031{
1032 struct l2cap_conn *conn = chan->conn;
1033 struct l2cap_conn_req req;
1034
1035 req.scid = cpu_to_le16(chan->scid);
1036 req.psm = chan->psm;
1037
1038 chan->ident = l2cap_get_ident(conn);
1039
1040 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1041
1042 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1043}
1044
Mat Martineau8eb200b2012-10-23 15:24:17 -07001045static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1046{
1047 struct l2cap_create_chan_req req;
1048 req.scid = cpu_to_le16(chan->scid);
1049 req.psm = chan->psm;
1050 req.amp_id = amp_id;
1051
1052 chan->ident = l2cap_get_ident(chan->conn);
1053
1054 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1055 sizeof(req), &req);
1056}
1057
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001058static void l2cap_move_setup(struct l2cap_chan *chan)
1059{
1060 struct sk_buff *skb;
1061
1062 BT_DBG("chan %p", chan);
1063
1064 if (chan->mode != L2CAP_MODE_ERTM)
1065 return;
1066
1067 __clear_retrans_timer(chan);
1068 __clear_monitor_timer(chan);
1069 __clear_ack_timer(chan);
1070
1071 chan->retry_count = 0;
1072 skb_queue_walk(&chan->tx_q, skb) {
1073 if (bt_cb(skb)->control.retries)
1074 bt_cb(skb)->control.retries = 1;
1075 else
1076 break;
1077 }
1078
1079 chan->expected_tx_seq = chan->buffer_seq;
1080
1081 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1082 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1083 l2cap_seq_list_clear(&chan->retrans_list);
1084 l2cap_seq_list_clear(&chan->srej_list);
1085 skb_queue_purge(&chan->srej_q);
1086
1087 chan->tx_state = L2CAP_TX_STATE_XMIT;
1088 chan->rx_state = L2CAP_RX_STATE_MOVE;
1089
1090 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1091}
1092
Mat Martineau5f3847a2012-10-23 15:24:12 -07001093static void l2cap_move_done(struct l2cap_chan *chan)
1094{
1095 u8 move_role = chan->move_role;
1096 BT_DBG("chan %p", chan);
1097
1098 chan->move_state = L2CAP_MOVE_STABLE;
1099 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1100
1101 if (chan->mode != L2CAP_MODE_ERTM)
1102 return;
1103
1104 switch (move_role) {
1105 case L2CAP_MOVE_ROLE_INITIATOR:
1106 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1107 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1108 break;
1109 case L2CAP_MOVE_ROLE_RESPONDER:
1110 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1111 break;
1112 }
1113}
1114
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001115static void l2cap_chan_ready(struct l2cap_chan *chan)
1116{
Mat Martineau28270112012-05-17 21:14:09 -07001117 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001118 chan->conf_state = 0;
1119 __clear_chan_timer(chan);
1120
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001121 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001122
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001123 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001124}
1125
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001126static void l2cap_start_connection(struct l2cap_chan *chan)
1127{
1128 if (__amp_capable(chan)) {
1129 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1130 a2mp_discover_amp(chan);
1131 } else {
1132 l2cap_send_conn_req(chan);
1133 }
1134}
1135
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001136static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001137{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001138 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001139
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001140 if (conn->hcon->type == LE_LINK) {
1141 l2cap_chan_ready(chan);
1142 return;
1143 }
1144
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001145 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001146 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1147 return;
1148
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001149 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001150 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001151 l2cap_start_connection(chan);
1152 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001153 } else {
1154 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001155 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001156
1157 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1158 conn->info_ident = l2cap_get_ident(conn);
1159
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001160 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001161
Gustavo Padovan2d792812012-10-06 10:07:01 +01001162 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1163 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001164 }
1165}
1166
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001167static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1168{
1169 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001170 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001171 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1172
1173 switch (mode) {
1174 case L2CAP_MODE_ERTM:
1175 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1176 case L2CAP_MODE_STREAMING:
1177 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1178 default:
1179 return 0x00;
1180 }
1181}
1182
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001183static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001184{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001185 struct sock *sk = chan->sk;
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001186 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001187 struct l2cap_disconn_req req;
1188
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001189 if (!conn)
1190 return;
1191
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001192 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001193 __clear_retrans_timer(chan);
1194 __clear_monitor_timer(chan);
1195 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001196 }
1197
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001198 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001199 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001200 return;
1201 }
1202
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001203 req.dcid = cpu_to_le16(chan->dcid);
1204 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001205 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1206 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001207
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001208 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001209 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001210 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001211 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001212}
1213
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001215static void l2cap_conn_start(struct l2cap_conn *conn)
1216{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001217 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001218
1219 BT_DBG("conn %p", conn);
1220
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001221 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001222
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001223 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001224 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001225
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001226 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001227
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001228 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001229 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001230 continue;
1231 }
1232
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001233 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001234 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001235 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001236 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001237 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001238 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001239
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001240 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001241 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001242 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001243 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001244 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001245 continue;
1246 }
1247
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001248 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001249
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001250 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001251 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001252 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001253 rsp.scid = cpu_to_le16(chan->dcid);
1254 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001255
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001256 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001257 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001258 if (test_bit(BT_SK_DEFER_SETUP,
1259 &bt_sk(sk)->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001260 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1261 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001262 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001263
1264 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001265 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001266 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1267 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001268 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001269 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001270 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001271 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1272 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001273 }
1274
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001275 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001276 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001277
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001278 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001279 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001280 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001281 continue;
1282 }
1283
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001284 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001285 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001286 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001287 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001288 }
1289
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001290 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001291 }
1292
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001293 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001294}
1295
Ido Yarivc2287682012-04-20 15:46:07 -03001296/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001297 * Returns closest match, locked.
1298 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001299static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001300 bdaddr_t *src,
1301 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001302{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001303 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001304
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001305 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001306
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001307 list_for_each_entry(c, &chan_list, global_l) {
1308 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001309
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001310 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001311 continue;
1312
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001313 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001314 int src_match, dst_match;
1315 int src_any, dst_any;
1316
Ville Tervob62f3282011-02-10 22:38:50 -03001317 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001318 src_match = !bacmp(&bt_sk(sk)->src, src);
1319 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1320 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001321 read_unlock(&chan_list_lock);
1322 return c;
1323 }
Ville Tervob62f3282011-02-10 22:38:50 -03001324
1325 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001326 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1327 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1328 if ((src_match && dst_any) || (src_any && dst_match) ||
1329 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001330 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001331 }
1332 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001333
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001334 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001335
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001336 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001337}
1338
1339static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1340{
Gustavo F. Padovanc916fbe2011-04-04 16:00:55 -03001341 struct sock *parent, *sk;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001342 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001343
1344 BT_DBG("");
1345
1346 /* Check if we have socket listening on cid */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001347 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
Ido Yarivc2287682012-04-20 15:46:07 -03001348 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001349 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001350 return;
1351
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001352 parent = pchan->sk;
1353
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001354 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001355
Gustavo Padovan80b98022012-05-27 22:27:51 -03001356 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001357 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001358 goto clean;
1359
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001360 sk = chan->sk;
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001361
Ville Tervob62f3282011-02-10 22:38:50 -03001362 hci_conn_hold(conn->hcon);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001363 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
Ville Tervob62f3282011-02-10 22:38:50 -03001364
Ville Tervob62f3282011-02-10 22:38:50 -03001365 bacpy(&bt_sk(sk)->src, conn->src);
1366 bacpy(&bt_sk(sk)->dst, conn->dst);
1367
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001368 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001369
Gustavo Padovan6754e0d2012-05-25 09:30:56 -03001370 l2cap_chan_ready(chan);
Ville Tervob62f3282011-02-10 22:38:50 -03001371
Ville Tervob62f3282011-02-10 22:38:50 -03001372clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001373 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001374}
1375
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001376static void l2cap_conn_ready(struct l2cap_conn *conn)
1377{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001378 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001379 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001380
1381 BT_DBG("conn %p", conn);
1382
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001383 if (!hcon->out && hcon->type == LE_LINK)
Ville Tervob62f3282011-02-10 22:38:50 -03001384 l2cap_le_conn_ready(conn);
1385
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001386 if (hcon->out && hcon->type == LE_LINK)
1387 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001388
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001389 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001390
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001391 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001392
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001393 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001394
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001395 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1396 l2cap_chan_unlock(chan);
1397 continue;
1398 }
1399
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001400 if (hcon->type == LE_LINK) {
1401 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001402 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001403
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001404 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001405 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001406 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001407 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001408 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001409 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001410 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001411
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001412 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001413 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001414
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001415 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001416 }
1417
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001418 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001419}
1420
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001421/* Notify sockets that we cannot guaranty reliability anymore */
1422static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1423{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001424 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001425
1426 BT_DBG("conn %p", conn);
1427
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001428 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001429
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001430 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001431 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001432 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001433 }
1434
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001435 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001436}
1437
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001438static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001439{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001440 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001441 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001442
Marcel Holtmann984947d2009-02-06 23:35:19 +01001443 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001444 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001445
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001446 l2cap_conn_start(conn);
1447}
1448
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001449static void l2cap_conn_del(struct hci_conn *hcon, int err)
1450{
1451 struct l2cap_conn *conn = hcon->l2cap_data;
1452 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001453
1454 if (!conn)
1455 return;
1456
1457 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1458
1459 kfree_skb(conn->rx_skb);
1460
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001461 mutex_lock(&conn->chan_lock);
1462
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001463 /* Kill channels */
1464 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001465 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001466 l2cap_chan_lock(chan);
1467
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001468 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001469
1470 l2cap_chan_unlock(chan);
1471
Gustavo Padovan80b98022012-05-27 22:27:51 -03001472 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001473 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001474 }
1475
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001476 mutex_unlock(&conn->chan_lock);
1477
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001478 hci_chan_del(conn->hchan);
1479
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001480 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001481 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001482
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001483 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001484 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001485 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001486 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001487
1488 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001489 conn->hchan = NULL;
1490 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001491}
1492
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001493static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001494{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001495 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001496 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001497
Johan Hedbergd06cc412012-06-06 18:44:11 +08001498 BT_DBG("conn %p", conn);
1499
1500 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1501 smp_chan_destroy(conn);
1502 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1503 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001504}
1505
Claudio Takahasibaf43252013-04-11 13:55:50 -03001506static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507{
Marcel Holtmann01394182006-07-03 10:02:46 +02001508 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001509 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510
Claudio Takahasibaf43252013-04-11 13:55:50 -03001511 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512 return conn;
1513
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001514 hchan = hci_chan_create(hcon);
1515 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001518 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001519 if (!conn) {
1520 hci_chan_del(hchan);
1521 return NULL;
1522 }
1523
David Herrmann9c903e32013-04-06 20:28:44 +02001524 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525 hcon->l2cap_data = conn;
1526 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001527 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001528 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001530 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001531
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001532 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001533 case LE_LINK:
1534 if (hcon->hdev->le_mtu) {
1535 conn->mtu = hcon->hdev->le_mtu;
1536 break;
1537 }
1538 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001539 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001540 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001541 break;
1542 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001543
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544 conn->src = &hcon->hdev->bdaddr;
1545 conn->dst = &hcon->dst;
1546
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001547 conn->feat_mask = 0;
1548
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001550 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001551
1552 INIT_LIST_HEAD(&conn->chan_l);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001554 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001555 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001556 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001557 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001558
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001559 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001560
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561 return conn;
1562}
1563
David Herrmann9c903e32013-04-06 20:28:44 +02001564static void l2cap_conn_free(struct kref *ref)
1565{
1566 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1567
1568 hci_conn_put(conn->hcon);
1569 kfree(conn);
1570}
1571
1572void l2cap_conn_get(struct l2cap_conn *conn)
1573{
1574 kref_get(&conn->ref);
1575}
1576EXPORT_SYMBOL(l2cap_conn_get);
1577
1578void l2cap_conn_put(struct l2cap_conn *conn)
1579{
1580 kref_put(&conn->ref, l2cap_conn_free);
1581}
1582EXPORT_SYMBOL(l2cap_conn_put);
1583
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585
Ido Yarivc2287682012-04-20 15:46:07 -03001586/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587 * Returns closest match.
1588 */
Ido Yarivc2287682012-04-20 15:46:07 -03001589static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1590 bdaddr_t *src,
1591 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001593 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001595 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001596
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001597 list_for_each_entry(c, &chan_list, global_l) {
1598 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001599
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001600 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601 continue;
1602
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001603 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001604 int src_match, dst_match;
1605 int src_any, dst_any;
1606
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001608 src_match = !bacmp(&bt_sk(sk)->src, src);
1609 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1610 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001611 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001612 return c;
1613 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614
1615 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001616 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1617 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1618 if ((src_match && dst_any) || (src_any && dst_match) ||
1619 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001620 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621 }
1622 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001624 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001625
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001626 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627}
1628
Andre Guedes8e9f9892012-04-24 21:02:55 -03001629int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1630 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001631{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001632 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001633 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634 struct l2cap_conn *conn;
1635 struct hci_conn *hcon;
1636 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001637 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001638 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001640 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301641 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001643 hdev = hci_get_route(dst, src);
1644 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001645 return -EHOSTUNREACH;
1646
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001647 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001649 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001650
1651 /* PSM must be odd and lsb of upper byte must be 0 */
1652 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001653 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001654 err = -EINVAL;
1655 goto done;
1656 }
1657
1658 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1659 err = -EINVAL;
1660 goto done;
1661 }
1662
1663 switch (chan->mode) {
1664 case L2CAP_MODE_BASIC:
1665 break;
1666 case L2CAP_MODE_ERTM:
1667 case L2CAP_MODE_STREAMING:
1668 if (!disable_ertm)
1669 break;
1670 /* fall through */
1671 default:
1672 err = -ENOTSUPP;
1673 goto done;
1674 }
1675
Gustavo Padovan0797e012012-05-27 22:27:54 -03001676 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001677 case BT_CONNECT:
1678 case BT_CONNECT2:
1679 case BT_CONFIG:
1680 /* Already connecting */
1681 err = 0;
1682 goto done;
1683
1684 case BT_CONNECTED:
1685 /* Already connected */
1686 err = -EISCONN;
1687 goto done;
1688
1689 case BT_OPEN:
1690 case BT_BOUND:
1691 /* Can connect */
1692 break;
1693
1694 default:
1695 err = -EBADFD;
1696 goto done;
1697 }
1698
1699 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001700 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001701 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001702 release_sock(sk);
1703
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001704 chan->psm = psm;
1705 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001707 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001708
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001709 if (chan->dcid == L2CAP_CID_LE_DATA)
Andre Guedes8e9f9892012-04-24 21:02:55 -03001710 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001711 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001712 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001713 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001714 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001715
Ville Tervo30e76272011-02-22 16:10:53 -03001716 if (IS_ERR(hcon)) {
1717 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001719 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720
Claudio Takahasibaf43252013-04-11 13:55:50 -03001721 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001723 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001724 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 goto done;
1726 }
1727
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001728 if (hcon->type == LE_LINK) {
1729 err = 0;
1730
1731 if (!list_empty(&conn->chan_l)) {
1732 err = -EBUSY;
David Herrmann76a68ba2013-04-06 20:28:37 +02001733 hci_conn_drop(hcon);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001734 }
1735
1736 if (err)
1737 goto done;
1738 }
1739
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740 /* Update source addr of the socket */
1741 bacpy(src, conn->src);
1742
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001743 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001744 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001745 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001746
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001747 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001748 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749
1750 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001751 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001752 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001753 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001754 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001755 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001756 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757 }
1758
Ville Tervo30e76272011-02-22 16:10:53 -03001759 err = 0;
1760
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001762 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001763 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764 hci_dev_put(hdev);
1765 return err;
1766}
1767
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001768int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001769{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001770 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001771 DECLARE_WAITQUEUE(wait, current);
1772 int err = 0;
1773 int timeo = HZ/5;
1774
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001775 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001776 set_current_state(TASK_INTERRUPTIBLE);
1777 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001778 if (!timeo)
1779 timeo = HZ/5;
1780
1781 if (signal_pending(current)) {
1782 err = sock_intr_errno(timeo);
1783 break;
1784 }
1785
1786 release_sock(sk);
1787 timeo = schedule_timeout(timeo);
1788 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001789 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001790
1791 err = sock_error(sk);
1792 if (err)
1793 break;
1794 }
1795 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001796 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001797 return err;
1798}
1799
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001800static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001801{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001802 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001803 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001804
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001805 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001806
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001807 l2cap_chan_lock(chan);
1808
Mat Martineau80909e02012-05-17 20:53:50 -07001809 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001810 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001811 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001812 return;
1813 }
1814
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001815 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001816
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001817 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001818 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001819}
1820
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001821static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001822{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001823 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001824 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001825
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001826 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001827
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001828 l2cap_chan_lock(chan);
1829
Mat Martineau80909e02012-05-17 20:53:50 -07001830 if (!chan->conn) {
1831 l2cap_chan_unlock(chan);
1832 l2cap_chan_put(chan);
1833 return;
1834 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001835
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001836 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001837 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001838 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001839}
1840
Gustavo Padovand6603662012-05-21 13:58:22 -03001841static void l2cap_streaming_send(struct l2cap_chan *chan,
1842 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001843{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001844 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001845 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001846
Mat Martineau37339372012-05-17 20:53:33 -07001847 BT_DBG("chan %p, skbs %p", chan, skbs);
1848
Mat Martineaub99e13a2012-10-23 15:24:19 -07001849 if (__chan_is_moving(chan))
1850 return;
1851
Mat Martineau37339372012-05-17 20:53:33 -07001852 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1853
1854 while (!skb_queue_empty(&chan->tx_q)) {
1855
1856 skb = skb_dequeue(&chan->tx_q);
1857
1858 bt_cb(skb)->control.retries = 1;
1859 control = &bt_cb(skb)->control;
1860
1861 control->reqseq = 0;
1862 control->txseq = chan->next_tx_seq;
1863
1864 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001865
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001866 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001867 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1868 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001869 }
1870
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001871 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001872
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001873 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001874
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001875 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001876 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001877 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001878}
1879
Szymon Janc67c9e842011-07-28 16:24:33 +02001880static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001881{
1882 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001883 struct l2cap_ctrl *control;
1884 int sent = 0;
1885
1886 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001887
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001888 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001889 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001890
Mat Martineau94122bb2012-05-02 09:42:02 -07001891 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1892 return 0;
1893
Mat Martineaub99e13a2012-10-23 15:24:19 -07001894 if (__chan_is_moving(chan))
1895 return 0;
1896
Mat Martineau18a48e72012-05-17 20:53:34 -07001897 while (chan->tx_send_head &&
1898 chan->unacked_frames < chan->remote_tx_win &&
1899 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001900
Mat Martineau18a48e72012-05-17 20:53:34 -07001901 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001902
Mat Martineau18a48e72012-05-17 20:53:34 -07001903 bt_cb(skb)->control.retries = 1;
1904 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001905
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001906 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001907 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001908
Mat Martineau18a48e72012-05-17 20:53:34 -07001909 control->reqseq = chan->buffer_seq;
1910 chan->last_acked_seq = chan->buffer_seq;
1911 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001912
Mat Martineau18a48e72012-05-17 20:53:34 -07001913 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001914
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001915 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001916 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1917 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001918 }
1919
Mat Martineau18a48e72012-05-17 20:53:34 -07001920 /* Clone after data has been modified. Data is assumed to be
1921 read-only (for locking purposes) on cloned sk_buffs.
1922 */
1923 tx_skb = skb_clone(skb, GFP_KERNEL);
1924
1925 if (!tx_skb)
1926 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001927
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001928 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001929
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001930 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07001931 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03001932 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07001933 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001934
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001935 if (skb_queue_is_last(&chan->tx_q, skb))
1936 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001937 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001938 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07001939
1940 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001941 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001942 }
1943
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001944 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
1945 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07001946
1947 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001948}
1949
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001950static void l2cap_ertm_resend(struct l2cap_chan *chan)
1951{
1952 struct l2cap_ctrl control;
1953 struct sk_buff *skb;
1954 struct sk_buff *tx_skb;
1955 u16 seq;
1956
1957 BT_DBG("chan %p", chan);
1958
1959 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1960 return;
1961
Mat Martineaub99e13a2012-10-23 15:24:19 -07001962 if (__chan_is_moving(chan))
1963 return;
1964
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001965 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
1966 seq = l2cap_seq_list_pop(&chan->retrans_list);
1967
1968 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
1969 if (!skb) {
1970 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01001971 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001972 continue;
1973 }
1974
1975 bt_cb(skb)->control.retries++;
1976 control = bt_cb(skb)->control;
1977
1978 if (chan->max_tx != 0 &&
1979 bt_cb(skb)->control.retries > chan->max_tx) {
1980 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001981 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001982 l2cap_seq_list_clear(&chan->retrans_list);
1983 break;
1984 }
1985
1986 control.reqseq = chan->buffer_seq;
1987 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
1988 control.final = 1;
1989 else
1990 control.final = 0;
1991
1992 if (skb_cloned(skb)) {
1993 /* Cloned sk_buffs are read-only, so we need a
1994 * writeable copy
1995 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001996 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001997 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001998 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001999 }
2000
2001 if (!tx_skb) {
2002 l2cap_seq_list_clear(&chan->retrans_list);
2003 break;
2004 }
2005
2006 /* Update skb contents */
2007 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2008 put_unaligned_le32(__pack_extended_control(&control),
2009 tx_skb->data + L2CAP_HDR_SIZE);
2010 } else {
2011 put_unaligned_le16(__pack_enhanced_control(&control),
2012 tx_skb->data + L2CAP_HDR_SIZE);
2013 }
2014
2015 if (chan->fcs == L2CAP_FCS_CRC16) {
2016 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2017 put_unaligned_le16(fcs, skb_put(tx_skb,
2018 L2CAP_FCS_SIZE));
2019 }
2020
2021 l2cap_do_send(chan, tx_skb);
2022
2023 BT_DBG("Resent txseq %d", control.txseq);
2024
2025 chan->last_acked_seq = chan->buffer_seq;
2026 }
2027}
2028
Mat Martineauf80842a2012-05-17 20:53:46 -07002029static void l2cap_retransmit(struct l2cap_chan *chan,
2030 struct l2cap_ctrl *control)
2031{
2032 BT_DBG("chan %p, control %p", chan, control);
2033
2034 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2035 l2cap_ertm_resend(chan);
2036}
2037
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002038static void l2cap_retransmit_all(struct l2cap_chan *chan,
2039 struct l2cap_ctrl *control)
2040{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002041 struct sk_buff *skb;
2042
2043 BT_DBG("chan %p, control %p", chan, control);
2044
2045 if (control->poll)
2046 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2047
2048 l2cap_seq_list_clear(&chan->retrans_list);
2049
2050 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2051 return;
2052
2053 if (chan->unacked_frames) {
2054 skb_queue_walk(&chan->tx_q, skb) {
2055 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002056 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002057 break;
2058 }
2059
2060 skb_queue_walk_from(&chan->tx_q, skb) {
2061 if (skb == chan->tx_send_head)
2062 break;
2063
2064 l2cap_seq_list_append(&chan->retrans_list,
2065 bt_cb(skb)->control.txseq);
2066 }
2067
2068 l2cap_ertm_resend(chan);
2069 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002070}
2071
Szymon Jancb17e73b2012-01-11 10:59:47 +01002072static void l2cap_send_ack(struct l2cap_chan *chan)
2073{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002074 struct l2cap_ctrl control;
2075 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2076 chan->last_acked_seq);
2077 int threshold;
2078
2079 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2080 chan, chan->last_acked_seq, chan->buffer_seq);
2081
2082 memset(&control, 0, sizeof(control));
2083 control.sframe = 1;
2084
2085 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2086 chan->rx_state == L2CAP_RX_STATE_RECV) {
2087 __clear_ack_timer(chan);
2088 control.super = L2CAP_SUPER_RNR;
2089 control.reqseq = chan->buffer_seq;
2090 l2cap_send_sframe(chan, &control);
2091 } else {
2092 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2093 l2cap_ertm_send(chan);
2094 /* If any i-frames were sent, they included an ack */
2095 if (chan->buffer_seq == chan->last_acked_seq)
2096 frames_to_ack = 0;
2097 }
2098
Mat Martineauc20f8e32012-07-10 05:47:07 -07002099 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002100 * Calculate without mul or div
2101 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002102 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002103 threshold += threshold << 1;
2104 threshold >>= 2;
2105
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002106 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002107 threshold);
2108
2109 if (frames_to_ack >= threshold) {
2110 __clear_ack_timer(chan);
2111 control.super = L2CAP_SUPER_RR;
2112 control.reqseq = chan->buffer_seq;
2113 l2cap_send_sframe(chan, &control);
2114 frames_to_ack = 0;
2115 }
2116
2117 if (frames_to_ack)
2118 __set_ack_timer(chan);
2119 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002120}
2121
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002122static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2123 struct msghdr *msg, int len,
2124 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002125{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002126 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002127 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002128 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002129
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002130 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002131 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002132
2133 sent += count;
2134 len -= count;
2135
2136 /* Continuation fragments (no L2CAP header) */
2137 frag = &skb_shinfo(skb)->frag_list;
2138 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002139 struct sk_buff *tmp;
2140
Linus Torvalds1da177e2005-04-16 15:20:36 -07002141 count = min_t(unsigned int, conn->mtu, len);
2142
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002143 tmp = chan->ops->alloc_skb(chan, count,
2144 msg->msg_flags & MSG_DONTWAIT);
2145 if (IS_ERR(tmp))
2146 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002147
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002148 *frag = tmp;
2149
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002150 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2151 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002152
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002153 (*frag)->priority = skb->priority;
2154
Linus Torvalds1da177e2005-04-16 15:20:36 -07002155 sent += count;
2156 len -= count;
2157
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002158 skb->len += (*frag)->len;
2159 skb->data_len += (*frag)->len;
2160
Linus Torvalds1da177e2005-04-16 15:20:36 -07002161 frag = &(*frag)->next;
2162 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002163
2164 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002165}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002166
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002167static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002168 struct msghdr *msg, size_t len,
2169 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002170{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002171 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002172 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002173 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002174 struct l2cap_hdr *lh;
2175
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002176 BT_DBG("chan %p len %zu priority %u", chan, len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002177
2178 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002179
2180 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002181 msg->msg_flags & MSG_DONTWAIT);
2182 if (IS_ERR(skb))
2183 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002184
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002185 skb->priority = priority;
2186
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002187 /* Create L2CAP header */
2188 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002189 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002190 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
2191 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002192
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002193 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002194 if (unlikely(err < 0)) {
2195 kfree_skb(skb);
2196 return ERR_PTR(err);
2197 }
2198 return skb;
2199}
2200
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002201static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002202 struct msghdr *msg, size_t len,
2203 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002204{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002205 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002206 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002207 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002208 struct l2cap_hdr *lh;
2209
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002210 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002211
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002212 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002213
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002214 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002215 msg->msg_flags & MSG_DONTWAIT);
2216 if (IS_ERR(skb))
2217 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002218
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002219 skb->priority = priority;
2220
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002221 /* Create L2CAP header */
2222 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002223 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002224 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002225
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002226 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002227 if (unlikely(err < 0)) {
2228 kfree_skb(skb);
2229 return ERR_PTR(err);
2230 }
2231 return skb;
2232}
2233
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002234static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002235 struct msghdr *msg, size_t len,
2236 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002237{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002238 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002239 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002240 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002241 struct l2cap_hdr *lh;
2242
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002243 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002244
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002245 if (!conn)
2246 return ERR_PTR(-ENOTCONN);
2247
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002248 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002249
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002250 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002251 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002252
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002253 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002254 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002255
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002256 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002257
2258 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002259 msg->msg_flags & MSG_DONTWAIT);
2260 if (IS_ERR(skb))
2261 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002262
2263 /* Create L2CAP header */
2264 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002265 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002266 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002267
Mat Martineau18a48e72012-05-17 20:53:34 -07002268 /* Control header is populated later */
2269 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2270 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2271 else
2272 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002273
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002274 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002275 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002276
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002277 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002278 if (unlikely(err < 0)) {
2279 kfree_skb(skb);
2280 return ERR_PTR(err);
2281 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002282
Mat Martineau18a48e72012-05-17 20:53:34 -07002283 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002284 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002285 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002286}
2287
Mat Martineau94122bb2012-05-02 09:42:02 -07002288static int l2cap_segment_sdu(struct l2cap_chan *chan,
2289 struct sk_buff_head *seg_queue,
2290 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002291{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002292 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002293 u16 sdu_len;
2294 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002295 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002296
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002297 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002298
Mat Martineau94122bb2012-05-02 09:42:02 -07002299 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2300 * so fragmented skbs are not used. The HCI layer's handling
2301 * of fragmented skbs is not compatible with ERTM's queueing.
2302 */
2303
2304 /* PDU size is derived from the HCI MTU */
2305 pdu_len = chan->conn->mtu;
2306
Mat Martineaua5495742012-10-23 15:24:21 -07002307 /* Constrain PDU size for BR/EDR connections */
2308 if (!chan->hs_hcon)
2309 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002310
2311 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002312 if (chan->fcs)
2313 pdu_len -= L2CAP_FCS_SIZE;
2314
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002315 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002316
2317 /* Remote device may have requested smaller PDUs */
2318 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2319
2320 if (len <= pdu_len) {
2321 sar = L2CAP_SAR_UNSEGMENTED;
2322 sdu_len = 0;
2323 pdu_len = len;
2324 } else {
2325 sar = L2CAP_SAR_START;
2326 sdu_len = len;
2327 pdu_len -= L2CAP_SDULEN_SIZE;
2328 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002329
2330 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002331 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002332
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002333 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002334 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002335 return PTR_ERR(skb);
2336 }
2337
Mat Martineau94122bb2012-05-02 09:42:02 -07002338 bt_cb(skb)->control.sar = sar;
2339 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002340
Mat Martineau94122bb2012-05-02 09:42:02 -07002341 len -= pdu_len;
2342 if (sdu_len) {
2343 sdu_len = 0;
2344 pdu_len += L2CAP_SDULEN_SIZE;
2345 }
2346
2347 if (len <= pdu_len) {
2348 sar = L2CAP_SAR_END;
2349 pdu_len = len;
2350 } else {
2351 sar = L2CAP_SAR_CONTINUE;
2352 }
2353 }
2354
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002355 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002356}
2357
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002358int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002359 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002360{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002361 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002362 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002363 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002364
2365 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002366 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002367 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002368 if (IS_ERR(skb))
2369 return PTR_ERR(skb);
2370
2371 l2cap_do_send(chan, skb);
2372 return len;
2373 }
2374
2375 switch (chan->mode) {
2376 case L2CAP_MODE_BASIC:
2377 /* Check outgoing MTU */
2378 if (len > chan->omtu)
2379 return -EMSGSIZE;
2380
2381 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002382 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002383 if (IS_ERR(skb))
2384 return PTR_ERR(skb);
2385
2386 l2cap_do_send(chan, skb);
2387 err = len;
2388 break;
2389
2390 case L2CAP_MODE_ERTM:
2391 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002392 /* Check outgoing MTU */
2393 if (len > chan->omtu) {
2394 err = -EMSGSIZE;
2395 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002396 }
2397
Mat Martineau94122bb2012-05-02 09:42:02 -07002398 __skb_queue_head_init(&seg_queue);
2399
2400 /* Do segmentation before calling in to the state machine,
2401 * since it's possible to block while waiting for memory
2402 * allocation.
2403 */
2404 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2405
2406 /* The channel could have been closed while segmenting,
2407 * check that it is still connected.
2408 */
2409 if (chan->state != BT_CONNECTED) {
2410 __skb_queue_purge(&seg_queue);
2411 err = -ENOTCONN;
2412 }
2413
2414 if (err)
2415 break;
2416
Mat Martineau37339372012-05-17 20:53:33 -07002417 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002418 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002419 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002420 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002421
Gustavo Padovand6603662012-05-21 13:58:22 -03002422 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002423
Mat Martineau94122bb2012-05-02 09:42:02 -07002424 /* If the skbs were not queued for sending, they'll still be in
2425 * seg_queue and need to be purged.
2426 */
2427 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002428 break;
2429
2430 default:
2431 BT_DBG("bad state %1.1x", chan->mode);
2432 err = -EBADFD;
2433 }
2434
2435 return err;
2436}
2437
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002438static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2439{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002440 struct l2cap_ctrl control;
2441 u16 seq;
2442
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002443 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002444
2445 memset(&control, 0, sizeof(control));
2446 control.sframe = 1;
2447 control.super = L2CAP_SUPER_SREJ;
2448
2449 for (seq = chan->expected_tx_seq; seq != txseq;
2450 seq = __next_seq(chan, seq)) {
2451 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2452 control.reqseq = seq;
2453 l2cap_send_sframe(chan, &control);
2454 l2cap_seq_list_append(&chan->srej_list, seq);
2455 }
2456 }
2457
2458 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002459}
2460
2461static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2462{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002463 struct l2cap_ctrl control;
2464
2465 BT_DBG("chan %p", chan);
2466
2467 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2468 return;
2469
2470 memset(&control, 0, sizeof(control));
2471 control.sframe = 1;
2472 control.super = L2CAP_SUPER_SREJ;
2473 control.reqseq = chan->srej_list.tail;
2474 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002475}
2476
2477static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2478{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002479 struct l2cap_ctrl control;
2480 u16 initial_head;
2481 u16 seq;
2482
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002483 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002484
2485 memset(&control, 0, sizeof(control));
2486 control.sframe = 1;
2487 control.super = L2CAP_SUPER_SREJ;
2488
2489 /* Capture initial list head to allow only one pass through the list. */
2490 initial_head = chan->srej_list.head;
2491
2492 do {
2493 seq = l2cap_seq_list_pop(&chan->srej_list);
2494 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2495 break;
2496
2497 control.reqseq = seq;
2498 l2cap_send_sframe(chan, &control);
2499 l2cap_seq_list_append(&chan->srej_list, seq);
2500 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002501}
2502
Mat Martineau608bcc62012-05-17 20:53:32 -07002503static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2504{
2505 struct sk_buff *acked_skb;
2506 u16 ackseq;
2507
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002508 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002509
2510 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2511 return;
2512
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002513 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002514 chan->expected_ack_seq, chan->unacked_frames);
2515
2516 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2517 ackseq = __next_seq(chan, ackseq)) {
2518
2519 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2520 if (acked_skb) {
2521 skb_unlink(acked_skb, &chan->tx_q);
2522 kfree_skb(acked_skb);
2523 chan->unacked_frames--;
2524 }
2525 }
2526
2527 chan->expected_ack_seq = reqseq;
2528
2529 if (chan->unacked_frames == 0)
2530 __clear_retrans_timer(chan);
2531
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002532 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002533}
2534
2535static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2536{
2537 BT_DBG("chan %p", chan);
2538
2539 chan->expected_tx_seq = chan->buffer_seq;
2540 l2cap_seq_list_clear(&chan->srej_list);
2541 skb_queue_purge(&chan->srej_q);
2542 chan->rx_state = L2CAP_RX_STATE_RECV;
2543}
2544
Gustavo Padovand6603662012-05-21 13:58:22 -03002545static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2546 struct l2cap_ctrl *control,
2547 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002548{
Mat Martineau608bcc62012-05-17 20:53:32 -07002549 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2550 event);
2551
2552 switch (event) {
2553 case L2CAP_EV_DATA_REQUEST:
2554 if (chan->tx_send_head == NULL)
2555 chan->tx_send_head = skb_peek(skbs);
2556
2557 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2558 l2cap_ertm_send(chan);
2559 break;
2560 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2561 BT_DBG("Enter LOCAL_BUSY");
2562 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2563
2564 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2565 /* The SREJ_SENT state must be aborted if we are to
2566 * enter the LOCAL_BUSY state.
2567 */
2568 l2cap_abort_rx_srej_sent(chan);
2569 }
2570
2571 l2cap_send_ack(chan);
2572
2573 break;
2574 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2575 BT_DBG("Exit LOCAL_BUSY");
2576 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2577
2578 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2579 struct l2cap_ctrl local_control;
2580
2581 memset(&local_control, 0, sizeof(local_control));
2582 local_control.sframe = 1;
2583 local_control.super = L2CAP_SUPER_RR;
2584 local_control.poll = 1;
2585 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002586 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002587
2588 chan->retry_count = 1;
2589 __set_monitor_timer(chan);
2590 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2591 }
2592 break;
2593 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2594 l2cap_process_reqseq(chan, control->reqseq);
2595 break;
2596 case L2CAP_EV_EXPLICIT_POLL:
2597 l2cap_send_rr_or_rnr(chan, 1);
2598 chan->retry_count = 1;
2599 __set_monitor_timer(chan);
2600 __clear_ack_timer(chan);
2601 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2602 break;
2603 case L2CAP_EV_RETRANS_TO:
2604 l2cap_send_rr_or_rnr(chan, 1);
2605 chan->retry_count = 1;
2606 __set_monitor_timer(chan);
2607 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2608 break;
2609 case L2CAP_EV_RECV_FBIT:
2610 /* Nothing to process */
2611 break;
2612 default:
2613 break;
2614 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002615}
2616
Gustavo Padovand6603662012-05-21 13:58:22 -03002617static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2618 struct l2cap_ctrl *control,
2619 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002620{
Mat Martineau608bcc62012-05-17 20:53:32 -07002621 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2622 event);
2623
2624 switch (event) {
2625 case L2CAP_EV_DATA_REQUEST:
2626 if (chan->tx_send_head == NULL)
2627 chan->tx_send_head = skb_peek(skbs);
2628 /* Queue data, but don't send. */
2629 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2630 break;
2631 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2632 BT_DBG("Enter LOCAL_BUSY");
2633 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2634
2635 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2636 /* The SREJ_SENT state must be aborted if we are to
2637 * enter the LOCAL_BUSY state.
2638 */
2639 l2cap_abort_rx_srej_sent(chan);
2640 }
2641
2642 l2cap_send_ack(chan);
2643
2644 break;
2645 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2646 BT_DBG("Exit LOCAL_BUSY");
2647 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2648
2649 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2650 struct l2cap_ctrl local_control;
2651 memset(&local_control, 0, sizeof(local_control));
2652 local_control.sframe = 1;
2653 local_control.super = L2CAP_SUPER_RR;
2654 local_control.poll = 1;
2655 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002656 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002657
2658 chan->retry_count = 1;
2659 __set_monitor_timer(chan);
2660 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2661 }
2662 break;
2663 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2664 l2cap_process_reqseq(chan, control->reqseq);
2665
2666 /* Fall through */
2667
2668 case L2CAP_EV_RECV_FBIT:
2669 if (control && control->final) {
2670 __clear_monitor_timer(chan);
2671 if (chan->unacked_frames > 0)
2672 __set_retrans_timer(chan);
2673 chan->retry_count = 0;
2674 chan->tx_state = L2CAP_TX_STATE_XMIT;
2675 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2676 }
2677 break;
2678 case L2CAP_EV_EXPLICIT_POLL:
2679 /* Ignore */
2680 break;
2681 case L2CAP_EV_MONITOR_TO:
2682 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2683 l2cap_send_rr_or_rnr(chan, 1);
2684 __set_monitor_timer(chan);
2685 chan->retry_count++;
2686 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002687 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002688 }
2689 break;
2690 default:
2691 break;
2692 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002693}
2694
Gustavo Padovand6603662012-05-21 13:58:22 -03002695static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2696 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002697{
Mat Martineau608bcc62012-05-17 20:53:32 -07002698 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2699 chan, control, skbs, event, chan->tx_state);
2700
2701 switch (chan->tx_state) {
2702 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002703 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002704 break;
2705 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002706 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002707 break;
2708 default:
2709 /* Ignore event */
2710 break;
2711 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002712}
2713
Mat Martineau4b51dae92012-05-17 20:53:37 -07002714static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2715 struct l2cap_ctrl *control)
2716{
2717 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002718 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002719}
2720
Mat Martineauf80842a2012-05-17 20:53:46 -07002721static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2722 struct l2cap_ctrl *control)
2723{
2724 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002725 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002726}
2727
Linus Torvalds1da177e2005-04-16 15:20:36 -07002728/* Copy frame to all raw sockets on that connection */
2729static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2730{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002731 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002732 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002733
2734 BT_DBG("conn %p", conn);
2735
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002736 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002737
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002738 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002739 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002740 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002741 continue;
2742
2743 /* Don't send frame to the socket it came from */
2744 if (skb->sk == sk)
2745 continue;
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002746 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002747 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002748 continue;
2749
Gustavo Padovan80b98022012-05-27 22:27:51 -03002750 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002751 kfree_skb(nskb);
2752 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002753
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002754 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002755}
2756
2757/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002758static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2759 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002760{
2761 struct sk_buff *skb, **frag;
2762 struct l2cap_cmd_hdr *cmd;
2763 struct l2cap_hdr *lh;
2764 int len, count;
2765
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002766 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2767 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002768
2769 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2770 count = min_t(unsigned int, conn->mtu, len);
2771
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002772 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002773 if (!skb)
2774 return NULL;
2775
2776 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002777 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002778
2779 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002780 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002781 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002782 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002783
2784 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2785 cmd->code = code;
2786 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002787 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002788
2789 if (dlen) {
2790 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2791 memcpy(skb_put(skb, count), data, count);
2792 data += count;
2793 }
2794
2795 len -= skb->len;
2796
2797 /* Continuation fragments (no L2CAP header) */
2798 frag = &skb_shinfo(skb)->frag_list;
2799 while (len) {
2800 count = min_t(unsigned int, conn->mtu, len);
2801
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002802 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002803 if (!*frag)
2804 goto fail;
2805
2806 memcpy(skb_put(*frag, count), data, count);
2807
2808 len -= count;
2809 data += count;
2810
2811 frag = &(*frag)->next;
2812 }
2813
2814 return skb;
2815
2816fail:
2817 kfree_skb(skb);
2818 return NULL;
2819}
2820
Gustavo Padovan2d792812012-10-06 10:07:01 +01002821static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2822 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002823{
2824 struct l2cap_conf_opt *opt = *ptr;
2825 int len;
2826
2827 len = L2CAP_CONF_OPT_SIZE + opt->len;
2828 *ptr += len;
2829
2830 *type = opt->type;
2831 *olen = opt->len;
2832
2833 switch (opt->len) {
2834 case 1:
2835 *val = *((u8 *) opt->val);
2836 break;
2837
2838 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002839 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002840 break;
2841
2842 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002843 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002844 break;
2845
2846 default:
2847 *val = (unsigned long) opt->val;
2848 break;
2849 }
2850
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002851 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002852 return len;
2853}
2854
Linus Torvalds1da177e2005-04-16 15:20:36 -07002855static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2856{
2857 struct l2cap_conf_opt *opt = *ptr;
2858
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002859 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002860
2861 opt->type = type;
2862 opt->len = len;
2863
2864 switch (len) {
2865 case 1:
2866 *((u8 *) opt->val) = val;
2867 break;
2868
2869 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002870 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002871 break;
2872
2873 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002874 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002875 break;
2876
2877 default:
2878 memcpy(opt->val, (void *) val, len);
2879 break;
2880 }
2881
2882 *ptr += L2CAP_CONF_OPT_SIZE + len;
2883}
2884
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002885static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2886{
2887 struct l2cap_conf_efs efs;
2888
Szymon Janc1ec918c2011-11-16 09:32:21 +01002889 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002890 case L2CAP_MODE_ERTM:
2891 efs.id = chan->local_id;
2892 efs.stype = chan->local_stype;
2893 efs.msdu = cpu_to_le16(chan->local_msdu);
2894 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002895 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002896 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002897 break;
2898
2899 case L2CAP_MODE_STREAMING:
2900 efs.id = 1;
2901 efs.stype = L2CAP_SERV_BESTEFFORT;
2902 efs.msdu = cpu_to_le16(chan->local_msdu);
2903 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2904 efs.acc_lat = 0;
2905 efs.flush_to = 0;
2906 break;
2907
2908 default:
2909 return;
2910 }
2911
2912 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002913 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002914}
2915
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002916static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002917{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002918 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07002919 ack_timer.work);
2920 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002921
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02002922 BT_DBG("chan %p", chan);
2923
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002924 l2cap_chan_lock(chan);
2925
Mat Martineau03625202012-05-17 20:53:51 -07002926 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2927 chan->last_acked_seq);
2928
2929 if (frames_to_ack)
2930 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002931
2932 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01002933 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002934}
2935
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03002936int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002937{
Mat Martineau3c588192012-04-11 10:48:42 -07002938 int err;
2939
Mat Martineau105bdf92012-04-27 16:50:48 -07002940 chan->next_tx_seq = 0;
2941 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002942 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002943 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002944 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002945 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07002946 chan->last_acked_seq = 0;
2947 chan->sdu = NULL;
2948 chan->sdu_last_frag = NULL;
2949 chan->sdu_len = 0;
2950
Mat Martineaud34c34f2012-05-14 14:49:27 -07002951 skb_queue_head_init(&chan->tx_q);
2952
Mat Martineau08333282012-10-23 15:24:06 -07002953 chan->local_amp_id = 0;
2954 chan->move_id = 0;
2955 chan->move_state = L2CAP_MOVE_STABLE;
2956 chan->move_role = L2CAP_MOVE_ROLE_NONE;
2957
Mat Martineau105bdf92012-04-27 16:50:48 -07002958 if (chan->mode != L2CAP_MODE_ERTM)
2959 return 0;
2960
2961 chan->rx_state = L2CAP_RX_STATE_RECV;
2962 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002963
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002964 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
2965 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
2966 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002967
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03002968 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002969
Mat Martineau3c588192012-04-11 10:48:42 -07002970 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
2971 if (err < 0)
2972 return err;
2973
Mat Martineau9dc9aff2012-05-17 16:20:14 -07002974 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
2975 if (err < 0)
2976 l2cap_seq_list_free(&chan->srej_list);
2977
2978 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002979}
2980
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002981static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2982{
2983 switch (mode) {
2984 case L2CAP_MODE_STREAMING:
2985 case L2CAP_MODE_ERTM:
2986 if (l2cap_mode_supported(mode, remote_feat_mask))
2987 return mode;
2988 /* fall through */
2989 default:
2990 return L2CAP_MODE_BASIC;
2991 }
2992}
2993
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002994static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
2995{
2996 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
2997}
2998
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002999static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
3000{
3001 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
3002}
3003
Mat Martineau36c86c82012-10-23 15:24:20 -07003004static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3005 struct l2cap_conf_rfc *rfc)
3006{
3007 if (chan->local_amp_id && chan->hs_hcon) {
3008 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3009
3010 /* Class 1 devices have must have ERTM timeouts
3011 * exceeding the Link Supervision Timeout. The
3012 * default Link Supervision Timeout for AMP
3013 * controllers is 10 seconds.
3014 *
3015 * Class 1 devices use 0xffffffff for their
3016 * best-effort flush timeout, so the clamping logic
3017 * will result in a timeout that meets the above
3018 * requirement. ERTM timeouts are 16-bit values, so
3019 * the maximum timeout is 65.535 seconds.
3020 */
3021
3022 /* Convert timeout to milliseconds and round */
3023 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3024
3025 /* This is the recommended formula for class 2 devices
3026 * that start ERTM timers when packets are sent to the
3027 * controller.
3028 */
3029 ertm_to = 3 * ertm_to + 500;
3030
3031 if (ertm_to > 0xffff)
3032 ertm_to = 0xffff;
3033
3034 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3035 rfc->monitor_timeout = rfc->retrans_timeout;
3036 } else {
3037 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3038 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3039 }
3040}
3041
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003042static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3043{
3044 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003045 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003046 /* use extended control field */
3047 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003048 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3049 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003050 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003051 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003052 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3053 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003054 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003055}
3056
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003057static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003058{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003059 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003060 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003061 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003062 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003063
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003064 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003065
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003066 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003067 goto done;
3068
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003069 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003070 case L2CAP_MODE_STREAMING:
3071 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003072 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003073 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003074
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003075 if (__l2cap_efs_supported(chan))
3076 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3077
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003078 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003079 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003080 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003081 break;
3082 }
3083
3084done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003085 if (chan->imtu != L2CAP_DEFAULT_MTU)
3086 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003087
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003088 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003089 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003090 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003091 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003092 break;
3093
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003094 rfc.mode = L2CAP_MODE_BASIC;
3095 rfc.txwin_size = 0;
3096 rfc.max_transmit = 0;
3097 rfc.retrans_timeout = 0;
3098 rfc.monitor_timeout = 0;
3099 rfc.max_pdu_size = 0;
3100
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003101 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003102 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003103 break;
3104
3105 case L2CAP_MODE_ERTM:
3106 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003107 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003108
3109 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003110
3111 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003112 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3113 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003114 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003115
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003116 l2cap_txwin_setup(chan);
3117
3118 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003119 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003120
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003121 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003122 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003123
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003124 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3125 l2cap_add_opt_efs(&ptr, chan);
3126
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003127 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3128 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003129 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003130
3131 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3132 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003133 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003134 chan->fcs = L2CAP_FCS_NONE;
3135 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3136 chan->fcs);
3137 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003138 break;
3139
3140 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003141 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003142 rfc.mode = L2CAP_MODE_STREAMING;
3143 rfc.txwin_size = 0;
3144 rfc.max_transmit = 0;
3145 rfc.retrans_timeout = 0;
3146 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003147
3148 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003149 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3150 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003151 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003152
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003153 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003154 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003155
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003156 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3157 l2cap_add_opt_efs(&ptr, chan);
3158
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003159 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3160 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003161 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003162 chan->fcs = L2CAP_FCS_NONE;
3163 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3164 chan->fcs);
3165 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003166 break;
3167 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003168
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003169 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003170 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003171
3172 return ptr - data;
3173}
3174
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003175static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003176{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003177 struct l2cap_conf_rsp *rsp = data;
3178 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003179 void *req = chan->conf_req;
3180 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003181 int type, hint, olen;
3182 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003183 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003184 struct l2cap_conf_efs efs;
3185 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003186 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003187 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003188 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003189
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003190 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003191
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003192 while (len >= L2CAP_CONF_OPT_SIZE) {
3193 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003194
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003195 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003196 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003197
3198 switch (type) {
3199 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003200 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003201 break;
3202
3203 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003204 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003205 break;
3206
3207 case L2CAP_CONF_QOS:
3208 break;
3209
Marcel Holtmann6464f352007-10-20 13:39:51 +02003210 case L2CAP_CONF_RFC:
3211 if (olen == sizeof(rfc))
3212 memcpy(&rfc, (void *) val, olen);
3213 break;
3214
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003215 case L2CAP_CONF_FCS:
3216 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003217 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003218 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003219
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003220 case L2CAP_CONF_EFS:
3221 remote_efs = 1;
3222 if (olen == sizeof(efs))
3223 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003224 break;
3225
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003226 case L2CAP_CONF_EWS:
3227 if (!enable_hs)
3228 return -ECONNREFUSED;
3229
3230 set_bit(FLAG_EXT_CTRL, &chan->flags);
3231 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003232 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003233 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003234 break;
3235
3236 default:
3237 if (hint)
3238 break;
3239
3240 result = L2CAP_CONF_UNKNOWN;
3241 *((u8 *) ptr++) = type;
3242 break;
3243 }
3244 }
3245
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003246 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003247 goto done;
3248
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003249 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003250 case L2CAP_MODE_STREAMING:
3251 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003252 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003253 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003254 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003255 break;
3256 }
3257
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003258 if (remote_efs) {
3259 if (__l2cap_efs_supported(chan))
3260 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3261 else
3262 return -ECONNREFUSED;
3263 }
3264
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003265 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003266 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003267
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003268 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003269 }
3270
3271done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003272 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003273 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003274 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003275
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003276 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003277 return -ECONNREFUSED;
3278
Gustavo Padovan2d792812012-10-06 10:07:01 +01003279 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3280 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003281 }
3282
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003283 if (result == L2CAP_CONF_SUCCESS) {
3284 /* Configure output options and let the other side know
3285 * which ones we don't like. */
3286
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003287 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3288 result = L2CAP_CONF_UNACCEPT;
3289 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003290 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003291 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003292 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003293 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003294
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003295 if (remote_efs) {
3296 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003297 efs.stype != L2CAP_SERV_NOTRAFIC &&
3298 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003299
3300 result = L2CAP_CONF_UNACCEPT;
3301
3302 if (chan->num_conf_req >= 1)
3303 return -ECONNREFUSED;
3304
3305 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003306 sizeof(efs),
3307 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003308 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003309 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003310 result = L2CAP_CONF_PENDING;
3311 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003312 }
3313 }
3314
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003315 switch (rfc.mode) {
3316 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003317 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003318 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003319 break;
3320
3321 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003322 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3323 chan->remote_tx_win = rfc.txwin_size;
3324 else
3325 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3326
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003327 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003328
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003329 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003330 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3331 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003332 rfc.max_pdu_size = cpu_to_le16(size);
3333 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003334
Mat Martineau36c86c82012-10-23 15:24:20 -07003335 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003336
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003337 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003338
3339 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003340 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003341
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003342 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3343 chan->remote_id = efs.id;
3344 chan->remote_stype = efs.stype;
3345 chan->remote_msdu = le16_to_cpu(efs.msdu);
3346 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003347 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003348 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003349 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003350 chan->remote_sdu_itime =
3351 le32_to_cpu(efs.sdu_itime);
3352 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003353 sizeof(efs),
3354 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003355 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003356 break;
3357
3358 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003359 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003360 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3361 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003362 rfc.max_pdu_size = cpu_to_le16(size);
3363 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003364
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003365 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003366
Gustavo Padovan2d792812012-10-06 10:07:01 +01003367 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3368 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003369
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003370 break;
3371
3372 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003373 result = L2CAP_CONF_UNACCEPT;
3374
3375 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003376 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003377 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003378
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003379 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003380 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003381 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003382 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003383 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003384 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003385
3386 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003387}
3388
Gustavo Padovan2d792812012-10-06 10:07:01 +01003389static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3390 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003391{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003392 struct l2cap_conf_req *req = data;
3393 void *ptr = req->data;
3394 int type, olen;
3395 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003396 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003397 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003398
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003399 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003400
3401 while (len >= L2CAP_CONF_OPT_SIZE) {
3402 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3403
3404 switch (type) {
3405 case L2CAP_CONF_MTU:
3406 if (val < L2CAP_DEFAULT_MIN_MTU) {
3407 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003408 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003409 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003410 chan->imtu = val;
3411 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003412 break;
3413
3414 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003415 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003416 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003417 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003418 break;
3419
3420 case L2CAP_CONF_RFC:
3421 if (olen == sizeof(rfc))
3422 memcpy(&rfc, (void *)val, olen);
3423
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003424 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003425 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003426 return -ECONNREFUSED;
3427
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003428 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003429
3430 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003431 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003432 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003433
3434 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003435 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003436 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003437 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003438 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003439
3440 case L2CAP_CONF_EFS:
3441 if (olen == sizeof(efs))
3442 memcpy(&efs, (void *)val, olen);
3443
3444 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003445 efs.stype != L2CAP_SERV_NOTRAFIC &&
3446 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003447 return -ECONNREFUSED;
3448
Gustavo Padovan2d792812012-10-06 10:07:01 +01003449 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3450 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003451 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003452
3453 case L2CAP_CONF_FCS:
3454 if (*result == L2CAP_CONF_PENDING)
3455 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003456 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003457 &chan->conf_state);
3458 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003459 }
3460 }
3461
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003462 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003463 return -ECONNREFUSED;
3464
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003465 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003466
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003467 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003468 switch (rfc.mode) {
3469 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003470 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3471 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3472 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003473 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3474 chan->ack_win = min_t(u16, chan->ack_win,
3475 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003476
3477 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3478 chan->local_msdu = le16_to_cpu(efs.msdu);
3479 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003480 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003481 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3482 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003483 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003484 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003485 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003486
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003487 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003488 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003489 }
3490 }
3491
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003492 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003493 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003494
3495 return ptr - data;
3496}
3497
Gustavo Padovan2d792812012-10-06 10:07:01 +01003498static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3499 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003500{
3501 struct l2cap_conf_rsp *rsp = data;
3502 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003503
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003504 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003505
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003506 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003507 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003508 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003509
3510 return ptr - data;
3511}
3512
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003513void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003514{
3515 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003516 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003517 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003518 u8 rsp_code;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003519
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003520 rsp.scid = cpu_to_le16(chan->dcid);
3521 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003522 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3523 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003524
3525 if (chan->hs_hcon)
3526 rsp_code = L2CAP_CREATE_CHAN_RSP;
3527 else
3528 rsp_code = L2CAP_CONN_RSP;
3529
3530 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3531
3532 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003533
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003534 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003535 return;
3536
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003537 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003538 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003539 chan->num_conf_req++;
3540}
3541
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003542static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003543{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003544 int type, olen;
3545 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003546 /* Use sane default values in case a misbehaving remote device
3547 * did not send an RFC or extended window size option.
3548 */
3549 u16 txwin_ext = chan->ack_win;
3550 struct l2cap_conf_rfc rfc = {
3551 .mode = chan->mode,
3552 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3553 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3554 .max_pdu_size = cpu_to_le16(chan->imtu),
3555 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3556 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003557
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003558 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003559
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003560 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003561 return;
3562
3563 while (len >= L2CAP_CONF_OPT_SIZE) {
3564 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3565
Mat Martineauc20f8e32012-07-10 05:47:07 -07003566 switch (type) {
3567 case L2CAP_CONF_RFC:
3568 if (olen == sizeof(rfc))
3569 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003570 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003571 case L2CAP_CONF_EWS:
3572 txwin_ext = val;
3573 break;
3574 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003575 }
3576
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003577 switch (rfc.mode) {
3578 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003579 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3580 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003581 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3582 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3583 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3584 else
3585 chan->ack_win = min_t(u16, chan->ack_win,
3586 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003587 break;
3588 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003589 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003590 }
3591}
3592
Gustavo Padovan2d792812012-10-06 10:07:01 +01003593static inline int l2cap_command_rej(struct l2cap_conn *conn,
3594 struct l2cap_cmd_hdr *cmd, u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003595{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003596 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003597
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003598 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003599 return 0;
3600
3601 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003602 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003603 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003604
3605 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003606 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003607
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003608 l2cap_conn_start(conn);
3609 }
3610
3611 return 0;
3612}
3613
Mat Martineau17009152012-10-23 15:24:07 -07003614static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3615 struct l2cap_cmd_hdr *cmd,
3616 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003617{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003618 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3619 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003620 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003621 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003622 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003623
3624 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003625 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003626
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003627 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003628
3629 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003630 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003631 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003632 result = L2CAP_CR_BAD_PSM;
3633 goto sendresp;
3634 }
3635
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003636 parent = pchan->sk;
3637
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003638 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003639 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003640
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003641 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003642 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003643 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003644 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003645 result = L2CAP_CR_SEC_BLOCK;
3646 goto response;
3647 }
3648
Linus Torvalds1da177e2005-04-16 15:20:36 -07003649 result = L2CAP_CR_NO_MEM;
3650
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003651 /* Check if we already have channel with that dcid */
3652 if (__l2cap_get_chan_by_dcid(conn, scid))
3653 goto response;
3654
Gustavo Padovan80b98022012-05-27 22:27:51 -03003655 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003656 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003657 goto response;
3658
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003659 sk = chan->sk;
3660
Linus Torvalds1da177e2005-04-16 15:20:36 -07003661 hci_conn_hold(conn->hcon);
3662
Linus Torvalds1da177e2005-04-16 15:20:36 -07003663 bacpy(&bt_sk(sk)->src, conn->src);
3664 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003665 chan->psm = psm;
3666 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003667 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003668
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003669 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003670
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003671 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003672
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003673 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003674
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003675 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003676
Marcel Holtmann984947d2009-02-06 23:35:19 +01003677 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003678 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003679 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003680 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003681 result = L2CAP_CR_PEND;
3682 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003683 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003684 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003685 /* Force pending result for AMP controllers.
3686 * The connection will succeed after the
3687 * physical link is up.
3688 */
3689 if (amp_id) {
3690 __l2cap_state_change(chan, BT_CONNECT2);
3691 result = L2CAP_CR_PEND;
3692 } else {
3693 __l2cap_state_change(chan, BT_CONFIG);
3694 result = L2CAP_CR_SUCCESS;
3695 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003696 status = L2CAP_CS_NO_INFO;
3697 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003698 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003699 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003700 result = L2CAP_CR_PEND;
3701 status = L2CAP_CS_AUTHEN_PEND;
3702 }
3703 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003704 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003705 result = L2CAP_CR_PEND;
3706 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003707 }
3708
Linus Torvalds1da177e2005-04-16 15:20:36 -07003709response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003710 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003711 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003712
3713sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003714 rsp.scid = cpu_to_le16(scid);
3715 rsp.dcid = cpu_to_le16(dcid);
3716 rsp.result = cpu_to_le16(result);
3717 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003718 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003719
3720 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3721 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003722 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003723
3724 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3725 conn->info_ident = l2cap_get_ident(conn);
3726
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003727 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003728
Gustavo Padovan2d792812012-10-06 10:07:01 +01003729 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3730 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003731 }
3732
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003733 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003734 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003735 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003736 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003737 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003738 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003739 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003740 }
Mat Martineau17009152012-10-23 15:24:07 -07003741
3742 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003743}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003744
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003745static int l2cap_connect_req(struct l2cap_conn *conn,
3746 struct l2cap_cmd_hdr *cmd, u8 *data)
3747{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303748 struct hci_dev *hdev = conn->hcon->hdev;
3749 struct hci_conn *hcon = conn->hcon;
3750
3751 hci_dev_lock(hdev);
3752 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3753 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3754 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3755 hcon->dst_type, 0, NULL, 0,
3756 hcon->dev_class);
3757 hci_dev_unlock(hdev);
3758
Gustavo Padovan300229f2012-10-12 19:40:40 +08003759 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003760 return 0;
3761}
3762
Mat Martineau5909cf32012-10-23 15:24:08 -07003763static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003764 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003765{
3766 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3767 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003768 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003769 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003770 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003771
3772 scid = __le16_to_cpu(rsp->scid);
3773 dcid = __le16_to_cpu(rsp->dcid);
3774 result = __le16_to_cpu(rsp->result);
3775 status = __le16_to_cpu(rsp->status);
3776
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003777 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 +01003778 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003779
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003780 mutex_lock(&conn->chan_lock);
3781
Linus Torvalds1da177e2005-04-16 15:20:36 -07003782 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003783 chan = __l2cap_get_chan_by_scid(conn, scid);
3784 if (!chan) {
3785 err = -EFAULT;
3786 goto unlock;
3787 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003788 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003789 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3790 if (!chan) {
3791 err = -EFAULT;
3792 goto unlock;
3793 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003794 }
3795
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003796 err = 0;
3797
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003798 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003799
Linus Torvalds1da177e2005-04-16 15:20:36 -07003800 switch (result) {
3801 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003802 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003803 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003804 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003805 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003806
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003807 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003808 break;
3809
Linus Torvalds1da177e2005-04-16 15:20:36 -07003810 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003811 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003812 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003813 break;
3814
3815 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003816 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003817 break;
3818
3819 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003820 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003821 break;
3822 }
3823
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003824 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003825
3826unlock:
3827 mutex_unlock(&conn->chan_lock);
3828
3829 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003830}
3831
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003832static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003833{
3834 /* FCS is enabled only in ERTM or streaming mode, if one or both
3835 * sides request it.
3836 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003837 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003838 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003839 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003840 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003841}
3842
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003843static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3844 u8 ident, u16 flags)
3845{
3846 struct l2cap_conn *conn = chan->conn;
3847
3848 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3849 flags);
3850
3851 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3852 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3853
3854 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
3855 l2cap_build_conf_rsp(chan, data,
3856 L2CAP_CONF_SUCCESS, flags), data);
3857}
3858
Gustavo Padovan2d792812012-10-06 10:07:01 +01003859static inline int l2cap_config_req(struct l2cap_conn *conn,
3860 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3861 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003862{
3863 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3864 u16 dcid, flags;
3865 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003866 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003867 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003868
3869 dcid = __le16_to_cpu(req->dcid);
3870 flags = __le16_to_cpu(req->flags);
3871
3872 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3873
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003874 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003875 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003876 return -ENOENT;
3877
David S. Miller033b1142011-07-21 13:38:42 -07003878 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003879 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003880
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003881 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003882 rej.scid = cpu_to_le16(chan->scid);
3883 rej.dcid = cpu_to_le16(chan->dcid);
3884
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003885 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003886 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003887 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003888 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003889
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003890 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003891 len = cmd_len - sizeof(*req);
Dan Rosenberg7ac28812011-06-24 08:38:05 -04003892 if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003893 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003894 l2cap_build_conf_rsp(chan, rsp,
3895 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003896 goto unlock;
3897 }
3898
3899 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003900 memcpy(chan->conf_req + chan->conf_len, req->data, len);
3901 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003902
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003903 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003904 /* Incomplete config. Send empty response. */
3905 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003906 l2cap_build_conf_rsp(chan, rsp,
3907 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003908 goto unlock;
3909 }
3910
3911 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003912 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003913 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02003914 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003915 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003916 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003917
Mat Martineau1500109b2012-10-23 15:24:15 -07003918 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003919 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003920 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003921
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003922 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003923 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003924
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003925 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02003926 goto unlock;
3927
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003928 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003929 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003930
Mat Martineau105bdf92012-04-27 16:50:48 -07003931 if (chan->mode == L2CAP_MODE_ERTM ||
3932 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003933 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003934
Mat Martineau3c588192012-04-11 10:48:42 -07003935 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02003936 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07003937 else
3938 l2cap_chan_ready(chan);
3939
Marcel Holtmann876d9482007-10-20 13:35:42 +02003940 goto unlock;
3941 }
3942
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003943 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003944 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003945 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003946 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003947 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003948 }
3949
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003950 /* Got Conf Rsp PENDING from remote side and asume we sent
3951 Conf Rsp PENDING in the code above */
3952 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003953 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003954
3955 /* check compatibility */
3956
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03003957 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02003958 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03003959 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
3960 else
3961 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003962 }
3963
Linus Torvalds1da177e2005-04-16 15:20:36 -07003964unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003965 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003966 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003967}
3968
Gustavo Padovan2d792812012-10-06 10:07:01 +01003969static inline int l2cap_config_rsp(struct l2cap_conn *conn,
3970 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003971{
3972 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3973 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003974 struct l2cap_chan *chan;
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003975 int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07003976 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003977
3978 scid = __le16_to_cpu(rsp->scid);
3979 flags = __le16_to_cpu(rsp->flags);
3980 result = __le16_to_cpu(rsp->result);
3981
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003982 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
3983 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003984
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003985 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003986 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003987 return 0;
3988
3989 switch (result) {
3990 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003991 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003992 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003993 break;
3994
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003995 case L2CAP_CONF_PENDING:
3996 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
3997
3998 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3999 char buf[64];
4000
4001 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004002 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004003 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004004 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004005 goto done;
4006 }
4007
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004008 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004009 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4010 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004011 } else {
4012 if (l2cap_check_efs(chan)) {
4013 amp_create_logical_link(chan);
4014 chan->ident = cmd->ident;
4015 }
4016 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004017 }
4018 goto done;
4019
Linus Torvalds1da177e2005-04-16 15:20:36 -07004020 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004021 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004022 char req[64];
4023
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004024 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004025 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004026 goto done;
4027 }
4028
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004029 /* throw out any old stored conf requests */
4030 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004031 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004032 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004033 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004034 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004035 goto done;
4036 }
4037
4038 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004039 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004040 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004041 if (result != L2CAP_CONF_SUCCESS)
4042 goto done;
4043 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004044 }
4045
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004046 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004047 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004048
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004049 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004050 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004051 goto done;
4052 }
4053
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004054 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004055 goto done;
4056
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004057 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004058
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004059 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004060 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004061
Mat Martineau105bdf92012-04-27 16:50:48 -07004062 if (chan->mode == L2CAP_MODE_ERTM ||
4063 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004064 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004065
Mat Martineau3c588192012-04-11 10:48:42 -07004066 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004067 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004068 else
4069 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004070 }
4071
4072done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004073 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004074 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004075}
4076
Gustavo Padovan2d792812012-10-06 10:07:01 +01004077static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
4078 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004079{
4080 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4081 struct l2cap_disconn_rsp rsp;
4082 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004083 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004084 struct sock *sk;
4085
4086 scid = __le16_to_cpu(req->scid);
4087 dcid = __le16_to_cpu(req->dcid);
4088
4089 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4090
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004091 mutex_lock(&conn->chan_lock);
4092
4093 chan = __l2cap_get_chan_by_scid(conn, dcid);
4094 if (!chan) {
4095 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004096 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004097 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004098
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004099 l2cap_chan_lock(chan);
4100
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004101 sk = chan->sk;
4102
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004103 rsp.dcid = cpu_to_le16(chan->scid);
4104 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004105 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4106
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004107 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004108 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004109 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004110
Mat Martineau61d6ef32012-04-27 16:50:50 -07004111 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004112 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004113
4114 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004115
Gustavo Padovan80b98022012-05-27 22:27:51 -03004116 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004117 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004118
4119 mutex_unlock(&conn->chan_lock);
4120
Linus Torvalds1da177e2005-04-16 15:20:36 -07004121 return 0;
4122}
4123
Gustavo Padovan2d792812012-10-06 10:07:01 +01004124static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
4125 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004126{
4127 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4128 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004129 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004130
4131 scid = __le16_to_cpu(rsp->scid);
4132 dcid = __le16_to_cpu(rsp->dcid);
4133
4134 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4135
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004136 mutex_lock(&conn->chan_lock);
4137
4138 chan = __l2cap_get_chan_by_scid(conn, scid);
4139 if (!chan) {
4140 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004141 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004142 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004143
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004144 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004145
Mat Martineau61d6ef32012-04-27 16:50:50 -07004146 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004147 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004148
4149 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004150
Gustavo Padovan80b98022012-05-27 22:27:51 -03004151 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004152 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004153
4154 mutex_unlock(&conn->chan_lock);
4155
Linus Torvalds1da177e2005-04-16 15:20:36 -07004156 return 0;
4157}
4158
Gustavo Padovan2d792812012-10-06 10:07:01 +01004159static inline int l2cap_information_req(struct l2cap_conn *conn,
4160 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004161{
4162 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004163 u16 type;
4164
4165 type = __le16_to_cpu(req->type);
4166
4167 BT_DBG("type 0x%4.4x", type);
4168
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004169 if (type == L2CAP_IT_FEAT_MASK) {
4170 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004171 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004172 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004173 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4174 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004175 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004176 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004177 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004178 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004179 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004180 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004181
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004182 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004183 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4184 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004185 } else if (type == L2CAP_IT_FIXED_CHAN) {
4186 u8 buf[12];
4187 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004188
4189 if (enable_hs)
4190 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4191 else
4192 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4193
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004194 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4195 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004196 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004197 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4198 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004199 } else {
4200 struct l2cap_info_rsp rsp;
4201 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004202 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004203 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4204 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004205 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004206
4207 return 0;
4208}
4209
Gustavo Padovan2d792812012-10-06 10:07:01 +01004210static inline int l2cap_information_rsp(struct l2cap_conn *conn,
4211 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004212{
4213 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4214 u16 type, result;
4215
4216 type = __le16_to_cpu(rsp->type);
4217 result = __le16_to_cpu(rsp->result);
4218
4219 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4220
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004221 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4222 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004223 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004224 return 0;
4225
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004226 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004227
Ville Tervoadb08ed2010-08-04 09:43:33 +03004228 if (result != L2CAP_IR_SUCCESS) {
4229 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4230 conn->info_ident = 0;
4231
4232 l2cap_conn_start(conn);
4233
4234 return 0;
4235 }
4236
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004237 switch (type) {
4238 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004239 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004240
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004241 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004242 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004243 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004244
4245 conn->info_ident = l2cap_get_ident(conn);
4246
4247 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004248 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004249 } else {
4250 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4251 conn->info_ident = 0;
4252
4253 l2cap_conn_start(conn);
4254 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004255 break;
4256
4257 case L2CAP_IT_FIXED_CHAN:
4258 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004259 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004260 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004261
4262 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004263 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004264 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004265
Linus Torvalds1da177e2005-04-16 15:20:36 -07004266 return 0;
4267}
4268
Mat Martineau17009152012-10-23 15:24:07 -07004269static int l2cap_create_channel_req(struct l2cap_conn *conn,
4270 struct l2cap_cmd_hdr *cmd,
4271 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004272{
4273 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004274 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004275 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004276 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004277 u16 psm, scid;
4278
4279 if (cmd_len != sizeof(*req))
4280 return -EPROTO;
4281
4282 if (!enable_hs)
4283 return -EINVAL;
4284
4285 psm = le16_to_cpu(req->psm);
4286 scid = le16_to_cpu(req->scid);
4287
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004288 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 -07004289
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004290 /* For controller id 0 make BR/EDR connection */
4291 if (req->amp_id == HCI_BREDR_ID) {
4292 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4293 req->amp_id);
4294 return 0;
4295 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004296
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004297 /* Validate AMP controller id */
4298 hdev = hci_dev_get(req->amp_id);
4299 if (!hdev)
4300 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004301
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004302 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004303 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004304 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004305 }
4306
4307 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4308 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004309 if (chan) {
4310 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4311 struct hci_conn *hs_hcon;
4312
4313 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, conn->dst);
4314 if (!hs_hcon) {
4315 hci_dev_put(hdev);
4316 return -EFAULT;
4317 }
4318
4319 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4320
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004321 mgr->bredr_chan = chan;
4322 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004323 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004324 conn->mtu = hdev->block_mtu;
4325 }
4326
4327 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004328
4329 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004330
4331error:
4332 rsp.dcid = 0;
4333 rsp.scid = cpu_to_le16(scid);
4334 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4335 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4336
4337 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4338 sizeof(rsp), &rsp);
4339
4340 return -EFAULT;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004341}
4342
Mat Martineau8eb200b2012-10-23 15:24:17 -07004343static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4344{
4345 struct l2cap_move_chan_req req;
4346 u8 ident;
4347
4348 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4349
4350 ident = l2cap_get_ident(chan->conn);
4351 chan->ident = ident;
4352
4353 req.icid = cpu_to_le16(chan->scid);
4354 req.dest_amp_id = dest_amp_id;
4355
4356 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4357 &req);
4358
4359 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4360}
4361
Mat Martineau1500109b2012-10-23 15:24:15 -07004362static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004363{
4364 struct l2cap_move_chan_rsp rsp;
4365
Mat Martineau1500109b2012-10-23 15:24:15 -07004366 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004367
Mat Martineau1500109b2012-10-23 15:24:15 -07004368 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004369 rsp.result = cpu_to_le16(result);
4370
Mat Martineau1500109b2012-10-23 15:24:15 -07004371 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4372 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004373}
4374
Mat Martineau5b155ef2012-10-23 15:24:14 -07004375static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004376{
4377 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004378
Mat Martineau5b155ef2012-10-23 15:24:14 -07004379 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004380
Mat Martineau5b155ef2012-10-23 15:24:14 -07004381 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004382
Mat Martineau5b155ef2012-10-23 15:24:14 -07004383 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004384 cfm.result = cpu_to_le16(result);
4385
Mat Martineau5b155ef2012-10-23 15:24:14 -07004386 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4387 sizeof(cfm), &cfm);
4388
4389 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4390}
4391
4392static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4393{
4394 struct l2cap_move_chan_cfm cfm;
4395
4396 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4397
4398 cfm.icid = cpu_to_le16(icid);
4399 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4400
4401 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4402 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004403}
4404
4405static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004406 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004407{
4408 struct l2cap_move_chan_cfm_rsp rsp;
4409
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004410 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004411
4412 rsp.icid = cpu_to_le16(icid);
4413 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4414}
4415
Mat Martineau5f3847a2012-10-23 15:24:12 -07004416static void __release_logical_link(struct l2cap_chan *chan)
4417{
4418 chan->hs_hchan = NULL;
4419 chan->hs_hcon = NULL;
4420
4421 /* Placeholder - release the logical link */
4422}
4423
Mat Martineau1500109b2012-10-23 15:24:15 -07004424static void l2cap_logical_fail(struct l2cap_chan *chan)
4425{
4426 /* Logical link setup failed */
4427 if (chan->state != BT_CONNECTED) {
4428 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004429 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004430 return;
4431 }
4432
4433 switch (chan->move_role) {
4434 case L2CAP_MOVE_ROLE_RESPONDER:
4435 l2cap_move_done(chan);
4436 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4437 break;
4438 case L2CAP_MOVE_ROLE_INITIATOR:
4439 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4440 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4441 /* Remote has only sent pending or
4442 * success responses, clean up
4443 */
4444 l2cap_move_done(chan);
4445 }
4446
4447 /* Other amp move states imply that the move
4448 * has already aborted
4449 */
4450 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4451 break;
4452 }
4453}
4454
4455static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4456 struct hci_chan *hchan)
4457{
4458 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004459
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004460 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004461 chan->hs_hcon->l2cap_data = chan->conn;
4462
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004463 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004464
4465 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004466 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004467
4468 set_default_fcs(chan);
4469
4470 err = l2cap_ertm_init(chan);
4471 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004472 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004473 else
4474 l2cap_chan_ready(chan);
4475 }
4476}
4477
4478static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4479 struct hci_chan *hchan)
4480{
4481 chan->hs_hcon = hchan->conn;
4482 chan->hs_hcon->l2cap_data = chan->conn;
4483
4484 BT_DBG("move_state %d", chan->move_state);
4485
4486 switch (chan->move_state) {
4487 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4488 /* Move confirm will be sent after a success
4489 * response is received
4490 */
4491 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4492 break;
4493 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4494 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4495 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4496 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4497 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4498 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4499 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4500 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4501 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4502 }
4503 break;
4504 default:
4505 /* Move was not in expected state, free the channel */
4506 __release_logical_link(chan);
4507
4508 chan->move_state = L2CAP_MOVE_STABLE;
4509 }
4510}
4511
4512/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004513void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4514 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004515{
Mat Martineau1500109b2012-10-23 15:24:15 -07004516 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4517
4518 if (status) {
4519 l2cap_logical_fail(chan);
4520 __release_logical_link(chan);
4521 return;
4522 }
4523
4524 if (chan->state != BT_CONNECTED) {
4525 /* Ignore logical link if channel is on BR/EDR */
4526 if (chan->local_amp_id)
4527 l2cap_logical_finish_create(chan, hchan);
4528 } else {
4529 l2cap_logical_finish_move(chan, hchan);
4530 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004531}
4532
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004533void l2cap_move_start(struct l2cap_chan *chan)
4534{
4535 BT_DBG("chan %p", chan);
4536
4537 if (chan->local_amp_id == HCI_BREDR_ID) {
4538 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4539 return;
4540 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4541 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4542 /* Placeholder - start physical link setup */
4543 } else {
4544 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4545 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4546 chan->move_id = 0;
4547 l2cap_move_setup(chan);
4548 l2cap_send_move_chan_req(chan, 0);
4549 }
4550}
4551
Mat Martineau8eb200b2012-10-23 15:24:17 -07004552static void l2cap_do_create(struct l2cap_chan *chan, int result,
4553 u8 local_amp_id, u8 remote_amp_id)
4554{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004555 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4556 local_amp_id, remote_amp_id);
4557
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004558 chan->fcs = L2CAP_FCS_NONE;
4559
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004560 /* Outgoing channel on AMP */
4561 if (chan->state == BT_CONNECT) {
4562 if (result == L2CAP_CR_SUCCESS) {
4563 chan->local_amp_id = local_amp_id;
4564 l2cap_send_create_chan_req(chan, remote_amp_id);
4565 } else {
4566 /* Revert to BR/EDR connect */
4567 l2cap_send_conn_req(chan);
4568 }
4569
4570 return;
4571 }
4572
4573 /* Incoming channel on AMP */
4574 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004575 struct l2cap_conn_rsp rsp;
4576 char buf[128];
4577 rsp.scid = cpu_to_le16(chan->dcid);
4578 rsp.dcid = cpu_to_le16(chan->scid);
4579
Mat Martineau8eb200b2012-10-23 15:24:17 -07004580 if (result == L2CAP_CR_SUCCESS) {
4581 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004582 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4583 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004584 } else {
4585 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004586 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4587 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004588 }
4589
4590 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4591 sizeof(rsp), &rsp);
4592
4593 if (result == L2CAP_CR_SUCCESS) {
4594 __l2cap_state_change(chan, BT_CONFIG);
4595 set_bit(CONF_REQ_SENT, &chan->conf_state);
4596 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4597 L2CAP_CONF_REQ,
4598 l2cap_build_conf_req(chan, buf), buf);
4599 chan->num_conf_req++;
4600 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004601 }
4602}
4603
4604static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4605 u8 remote_amp_id)
4606{
4607 l2cap_move_setup(chan);
4608 chan->move_id = local_amp_id;
4609 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4610
4611 l2cap_send_move_chan_req(chan, remote_amp_id);
4612}
4613
4614static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4615{
4616 struct hci_chan *hchan = NULL;
4617
4618 /* Placeholder - get hci_chan for logical link */
4619
4620 if (hchan) {
4621 if (hchan->state == BT_CONNECTED) {
4622 /* Logical link is ready to go */
4623 chan->hs_hcon = hchan->conn;
4624 chan->hs_hcon->l2cap_data = chan->conn;
4625 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4626 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4627
4628 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4629 } else {
4630 /* Wait for logical link to be ready */
4631 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4632 }
4633 } else {
4634 /* Logical link not available */
4635 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4636 }
4637}
4638
4639static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4640{
4641 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4642 u8 rsp_result;
4643 if (result == -EINVAL)
4644 rsp_result = L2CAP_MR_BAD_ID;
4645 else
4646 rsp_result = L2CAP_MR_NOT_ALLOWED;
4647
4648 l2cap_send_move_chan_rsp(chan, rsp_result);
4649 }
4650
4651 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4652 chan->move_state = L2CAP_MOVE_STABLE;
4653
4654 /* Restart data transmission */
4655 l2cap_ertm_send(chan);
4656}
4657
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004658/* Invoke with locked chan */
4659void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004660{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004661 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004662 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004663
Mat Martineau8eb200b2012-10-23 15:24:17 -07004664 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4665 chan, result, local_amp_id, remote_amp_id);
4666
Mat Martineau8eb200b2012-10-23 15:24:17 -07004667 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4668 l2cap_chan_unlock(chan);
4669 return;
4670 }
4671
4672 if (chan->state != BT_CONNECTED) {
4673 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4674 } else if (result != L2CAP_MR_SUCCESS) {
4675 l2cap_do_move_cancel(chan, result);
4676 } else {
4677 switch (chan->move_role) {
4678 case L2CAP_MOVE_ROLE_INITIATOR:
4679 l2cap_do_move_initiate(chan, local_amp_id,
4680 remote_amp_id);
4681 break;
4682 case L2CAP_MOVE_ROLE_RESPONDER:
4683 l2cap_do_move_respond(chan, result);
4684 break;
4685 default:
4686 l2cap_do_move_cancel(chan, result);
4687 break;
4688 }
4689 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004690}
4691
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004692static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004693 struct l2cap_cmd_hdr *cmd,
4694 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004695{
4696 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004697 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004698 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004699 u16 icid = 0;
4700 u16 result = L2CAP_MR_NOT_ALLOWED;
4701
4702 if (cmd_len != sizeof(*req))
4703 return -EPROTO;
4704
4705 icid = le16_to_cpu(req->icid);
4706
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004707 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004708
4709 if (!enable_hs)
4710 return -EINVAL;
4711
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004712 chan = l2cap_get_chan_by_dcid(conn, icid);
4713 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004714 rsp.icid = cpu_to_le16(icid);
4715 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4716 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4717 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004718 return 0;
4719 }
4720
Mat Martineau1500109b2012-10-23 15:24:15 -07004721 chan->ident = cmd->ident;
4722
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004723 if (chan->scid < L2CAP_CID_DYN_START ||
4724 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4725 (chan->mode != L2CAP_MODE_ERTM &&
4726 chan->mode != L2CAP_MODE_STREAMING)) {
4727 result = L2CAP_MR_NOT_ALLOWED;
4728 goto send_move_response;
4729 }
4730
4731 if (chan->local_amp_id == req->dest_amp_id) {
4732 result = L2CAP_MR_SAME_ID;
4733 goto send_move_response;
4734 }
4735
4736 if (req->dest_amp_id) {
4737 struct hci_dev *hdev;
4738 hdev = hci_dev_get(req->dest_amp_id);
4739 if (!hdev || hdev->dev_type != HCI_AMP ||
4740 !test_bit(HCI_UP, &hdev->flags)) {
4741 if (hdev)
4742 hci_dev_put(hdev);
4743
4744 result = L2CAP_MR_BAD_ID;
4745 goto send_move_response;
4746 }
4747 hci_dev_put(hdev);
4748 }
4749
4750 /* Detect a move collision. Only send a collision response
4751 * if this side has "lost", otherwise proceed with the move.
4752 * The winner has the larger bd_addr.
4753 */
4754 if ((__chan_is_moving(chan) ||
4755 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
4756 bacmp(conn->src, conn->dst) > 0) {
4757 result = L2CAP_MR_COLLISION;
4758 goto send_move_response;
4759 }
4760
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004761 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4762 l2cap_move_setup(chan);
4763 chan->move_id = req->dest_amp_id;
4764 icid = chan->dcid;
4765
4766 if (!req->dest_amp_id) {
4767 /* Moving to BR/EDR */
4768 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4769 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4770 result = L2CAP_MR_PEND;
4771 } else {
4772 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4773 result = L2CAP_MR_SUCCESS;
4774 }
4775 } else {
4776 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4777 /* Placeholder - uncomment when amp functions are available */
4778 /*amp_accept_physical(chan, req->dest_amp_id);*/
4779 result = L2CAP_MR_PEND;
4780 }
4781
4782send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004783 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004784
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004785 l2cap_chan_unlock(chan);
4786
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004787 return 0;
4788}
4789
Mat Martineau5b155ef2012-10-23 15:24:14 -07004790static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4791{
4792 struct l2cap_chan *chan;
4793 struct hci_chan *hchan = NULL;
4794
4795 chan = l2cap_get_chan_by_scid(conn, icid);
4796 if (!chan) {
4797 l2cap_send_move_chan_cfm_icid(conn, icid);
4798 return;
4799 }
4800
4801 __clear_chan_timer(chan);
4802 if (result == L2CAP_MR_PEND)
4803 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4804
4805 switch (chan->move_state) {
4806 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4807 /* Move confirm will be sent when logical link
4808 * is complete.
4809 */
4810 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4811 break;
4812 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4813 if (result == L2CAP_MR_PEND) {
4814 break;
4815 } else if (test_bit(CONN_LOCAL_BUSY,
4816 &chan->conn_state)) {
4817 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4818 } else {
4819 /* Logical link is up or moving to BR/EDR,
4820 * proceed with move
4821 */
4822 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4823 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4824 }
4825 break;
4826 case L2CAP_MOVE_WAIT_RSP:
4827 /* Moving to AMP */
4828 if (result == L2CAP_MR_SUCCESS) {
4829 /* Remote is ready, send confirm immediately
4830 * after logical link is ready
4831 */
4832 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4833 } else {
4834 /* Both logical link and move success
4835 * are required to confirm
4836 */
4837 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
4838 }
4839
4840 /* Placeholder - get hci_chan for logical link */
4841 if (!hchan) {
4842 /* Logical link not available */
4843 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4844 break;
4845 }
4846
4847 /* If the logical link is not yet connected, do not
4848 * send confirmation.
4849 */
4850 if (hchan->state != BT_CONNECTED)
4851 break;
4852
4853 /* Logical link is already ready to go */
4854
4855 chan->hs_hcon = hchan->conn;
4856 chan->hs_hcon->l2cap_data = chan->conn;
4857
4858 if (result == L2CAP_MR_SUCCESS) {
4859 /* Can confirm now */
4860 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4861 } else {
4862 /* Now only need move success
4863 * to confirm
4864 */
4865 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4866 }
4867
4868 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4869 break;
4870 default:
4871 /* Any other amp move state means the move failed. */
4872 chan->move_id = chan->local_amp_id;
4873 l2cap_move_done(chan);
4874 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4875 }
4876
4877 l2cap_chan_unlock(chan);
4878}
4879
4880static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
4881 u16 result)
4882{
4883 struct l2cap_chan *chan;
4884
4885 chan = l2cap_get_chan_by_ident(conn, ident);
4886 if (!chan) {
4887 /* Could not locate channel, icid is best guess */
4888 l2cap_send_move_chan_cfm_icid(conn, icid);
4889 return;
4890 }
4891
4892 __clear_chan_timer(chan);
4893
4894 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4895 if (result == L2CAP_MR_COLLISION) {
4896 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4897 } else {
4898 /* Cleanup - cancel move */
4899 chan->move_id = chan->local_amp_id;
4900 l2cap_move_done(chan);
4901 }
4902 }
4903
4904 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4905
4906 l2cap_chan_unlock(chan);
4907}
4908
4909static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
4910 struct l2cap_cmd_hdr *cmd,
4911 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004912{
4913 struct l2cap_move_chan_rsp *rsp = data;
4914 u16 icid, result;
4915
4916 if (cmd_len != sizeof(*rsp))
4917 return -EPROTO;
4918
4919 icid = le16_to_cpu(rsp->icid);
4920 result = le16_to_cpu(rsp->result);
4921
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004922 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004923
Mat Martineau5b155ef2012-10-23 15:24:14 -07004924 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
4925 l2cap_move_continue(conn, icid, result);
4926 else
4927 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004928
4929 return 0;
4930}
4931
Mat Martineau5f3847a2012-10-23 15:24:12 -07004932static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
4933 struct l2cap_cmd_hdr *cmd,
4934 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004935{
4936 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07004937 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004938 u16 icid, result;
4939
4940 if (cmd_len != sizeof(*cfm))
4941 return -EPROTO;
4942
4943 icid = le16_to_cpu(cfm->icid);
4944 result = le16_to_cpu(cfm->result);
4945
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004946 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004947
Mat Martineau5f3847a2012-10-23 15:24:12 -07004948 chan = l2cap_get_chan_by_dcid(conn, icid);
4949 if (!chan) {
4950 /* Spec requires a response even if the icid was not found */
4951 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4952 return 0;
4953 }
4954
4955 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
4956 if (result == L2CAP_MC_CONFIRMED) {
4957 chan->local_amp_id = chan->move_id;
4958 if (!chan->local_amp_id)
4959 __release_logical_link(chan);
4960 } else {
4961 chan->move_id = chan->local_amp_id;
4962 }
4963
4964 l2cap_move_done(chan);
4965 }
4966
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004967 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4968
Mat Martineau5f3847a2012-10-23 15:24:12 -07004969 l2cap_chan_unlock(chan);
4970
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004971 return 0;
4972}
4973
4974static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004975 struct l2cap_cmd_hdr *cmd,
4976 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004977{
4978 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07004979 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004980 u16 icid;
4981
4982 if (cmd_len != sizeof(*rsp))
4983 return -EPROTO;
4984
4985 icid = le16_to_cpu(rsp->icid);
4986
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004987 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004988
Mat Martineau3fd71a02012-10-23 15:24:16 -07004989 chan = l2cap_get_chan_by_scid(conn, icid);
4990 if (!chan)
4991 return 0;
4992
4993 __clear_chan_timer(chan);
4994
4995 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
4996 chan->local_amp_id = chan->move_id;
4997
4998 if (!chan->local_amp_id && chan->hs_hchan)
4999 __release_logical_link(chan);
5000
5001 l2cap_move_done(chan);
5002 }
5003
5004 l2cap_chan_unlock(chan);
5005
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005006 return 0;
5007}
5008
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005009static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005010 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005011{
5012 u16 max_latency;
5013
5014 if (min > max || min < 6 || max > 3200)
5015 return -EINVAL;
5016
5017 if (to_multiplier < 10 || to_multiplier > 3200)
5018 return -EINVAL;
5019
5020 if (max >= to_multiplier * 8)
5021 return -EINVAL;
5022
5023 max_latency = (to_multiplier * 8 / max) - 1;
5024 if (latency > 499 || latency > max_latency)
5025 return -EINVAL;
5026
5027 return 0;
5028}
5029
5030static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005031 struct l2cap_cmd_hdr *cmd,
5032 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005033{
5034 struct hci_conn *hcon = conn->hcon;
5035 struct l2cap_conn_param_update_req *req;
5036 struct l2cap_conn_param_update_rsp rsp;
5037 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005038 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005039
5040 if (!(hcon->link_mode & HCI_LM_MASTER))
5041 return -EINVAL;
5042
5043 cmd_len = __le16_to_cpu(cmd->len);
5044 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5045 return -EPROTO;
5046
5047 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005048 min = __le16_to_cpu(req->min);
5049 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005050 latency = __le16_to_cpu(req->latency);
5051 to_multiplier = __le16_to_cpu(req->to_multiplier);
5052
5053 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 +01005054 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005055
5056 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005057
5058 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5059 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005060 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005061 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005062 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005063
5064 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005065 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005066
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005067 if (!err)
5068 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5069
Claudio Takahaside731152011-02-11 19:28:55 -02005070 return 0;
5071}
5072
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005073static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005074 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5075 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005076{
5077 int err = 0;
5078
5079 switch (cmd->code) {
5080 case L2CAP_COMMAND_REJ:
5081 l2cap_command_rej(conn, cmd, data);
5082 break;
5083
5084 case L2CAP_CONN_REQ:
5085 err = l2cap_connect_req(conn, cmd, data);
5086 break;
5087
5088 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005089 case L2CAP_CREATE_CHAN_RSP:
Mat Martineau5909cf32012-10-23 15:24:08 -07005090 err = l2cap_connect_create_rsp(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005091 break;
5092
5093 case L2CAP_CONF_REQ:
5094 err = l2cap_config_req(conn, cmd, cmd_len, data);
5095 break;
5096
5097 case L2CAP_CONF_RSP:
5098 err = l2cap_config_rsp(conn, cmd, data);
5099 break;
5100
5101 case L2CAP_DISCONN_REQ:
5102 err = l2cap_disconnect_req(conn, cmd, data);
5103 break;
5104
5105 case L2CAP_DISCONN_RSP:
5106 err = l2cap_disconnect_rsp(conn, cmd, data);
5107 break;
5108
5109 case L2CAP_ECHO_REQ:
5110 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5111 break;
5112
5113 case L2CAP_ECHO_RSP:
5114 break;
5115
5116 case L2CAP_INFO_REQ:
5117 err = l2cap_information_req(conn, cmd, data);
5118 break;
5119
5120 case L2CAP_INFO_RSP:
5121 err = l2cap_information_rsp(conn, cmd, data);
5122 break;
5123
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005124 case L2CAP_CREATE_CHAN_REQ:
5125 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5126 break;
5127
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005128 case L2CAP_MOVE_CHAN_REQ:
5129 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5130 break;
5131
5132 case L2CAP_MOVE_CHAN_RSP:
5133 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
5134 break;
5135
5136 case L2CAP_MOVE_CHAN_CFM:
5137 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5138 break;
5139
5140 case L2CAP_MOVE_CHAN_CFM_RSP:
5141 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
5142 break;
5143
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005144 default:
5145 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5146 err = -EINVAL;
5147 break;
5148 }
5149
5150 return err;
5151}
5152
5153static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005154 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005155{
5156 switch (cmd->code) {
5157 case L2CAP_COMMAND_REJ:
5158 return 0;
5159
5160 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02005161 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005162
5163 case L2CAP_CONN_PARAM_UPDATE_RSP:
5164 return 0;
5165
5166 default:
5167 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5168 return -EINVAL;
5169 }
5170}
5171
5172static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005173 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005174{
5175 u8 *data = skb->data;
5176 int len = skb->len;
5177 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005178 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005179
5180 l2cap_raw_recv(conn, skb);
5181
5182 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005183 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005184 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5185 data += L2CAP_CMD_HDR_SIZE;
5186 len -= L2CAP_CMD_HDR_SIZE;
5187
Al Viro88219a02007-07-29 00:17:25 -07005188 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005189
Gustavo Padovan2d792812012-10-06 10:07:01 +01005190 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5191 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005192
Al Viro88219a02007-07-29 00:17:25 -07005193 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005194 BT_DBG("corrupted command");
5195 break;
5196 }
5197
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005198 if (conn->hcon->type == LE_LINK)
5199 err = l2cap_le_sig_cmd(conn, &cmd, data);
5200 else
5201 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005202
5203 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005204 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005205
5206 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005207
5208 /* FIXME: Map err to a valid reason */
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005209 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005210 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5211 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005212 }
5213
Al Viro88219a02007-07-29 00:17:25 -07005214 data += cmd_len;
5215 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005216 }
5217
5218 kfree_skb(skb);
5219}
5220
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005221static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005222{
5223 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005224 int hdr_size;
5225
5226 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5227 hdr_size = L2CAP_EXT_HDR_SIZE;
5228 else
5229 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005230
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005231 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005232 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005233 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5234 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5235
5236 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005237 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005238 }
5239 return 0;
5240}
5241
Mat Martineau6ea00482012-05-17 20:53:52 -07005242static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005243{
Mat Martineaue31f7632012-05-17 20:53:41 -07005244 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005245
Mat Martineaue31f7632012-05-17 20:53:41 -07005246 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005247
Mat Martineaue31f7632012-05-17 20:53:41 -07005248 memset(&control, 0, sizeof(control));
5249 control.sframe = 1;
5250 control.final = 1;
5251 control.reqseq = chan->buffer_seq;
5252 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005253
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005254 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005255 control.super = L2CAP_SUPER_RNR;
5256 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005257 }
5258
Mat Martineaue31f7632012-05-17 20:53:41 -07005259 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5260 chan->unacked_frames > 0)
5261 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005262
Mat Martineaue31f7632012-05-17 20:53:41 -07005263 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005264 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005265
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005266 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005267 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5268 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5269 * send it now.
5270 */
5271 control.super = L2CAP_SUPER_RR;
5272 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005273 }
5274}
5275
Gustavo Padovan2d792812012-10-06 10:07:01 +01005276static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5277 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005278{
Mat Martineau84084a32011-07-22 14:54:00 -07005279 /* skb->len reflects data in skb as well as all fragments
5280 * skb->data_len reflects only data in fragments
5281 */
5282 if (!skb_has_frag_list(skb))
5283 skb_shinfo(skb)->frag_list = new_frag;
5284
5285 new_frag->next = NULL;
5286
5287 (*last_frag)->next = new_frag;
5288 *last_frag = new_frag;
5289
5290 skb->len += new_frag->len;
5291 skb->data_len += new_frag->len;
5292 skb->truesize += new_frag->truesize;
5293}
5294
Mat Martineau4b51dae92012-05-17 20:53:37 -07005295static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5296 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005297{
5298 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005299
Mat Martineau4b51dae92012-05-17 20:53:37 -07005300 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005301 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005302 if (chan->sdu)
5303 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005304
Gustavo Padovan80b98022012-05-27 22:27:51 -03005305 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005306 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005307
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005308 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005309 if (chan->sdu)
5310 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005311
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005312 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005313 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005314
Mat Martineau84084a32011-07-22 14:54:00 -07005315 if (chan->sdu_len > chan->imtu) {
5316 err = -EMSGSIZE;
5317 break;
5318 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005319
Mat Martineau84084a32011-07-22 14:54:00 -07005320 if (skb->len >= chan->sdu_len)
5321 break;
5322
5323 chan->sdu = skb;
5324 chan->sdu_last_frag = skb;
5325
5326 skb = NULL;
5327 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005328 break;
5329
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005330 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005331 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005332 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005333
Mat Martineau84084a32011-07-22 14:54:00 -07005334 append_skb_frag(chan->sdu, skb,
5335 &chan->sdu_last_frag);
5336 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005337
Mat Martineau84084a32011-07-22 14:54:00 -07005338 if (chan->sdu->len >= chan->sdu_len)
5339 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005340
Mat Martineau84084a32011-07-22 14:54:00 -07005341 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005342 break;
5343
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005344 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005345 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005346 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005347
Mat Martineau84084a32011-07-22 14:54:00 -07005348 append_skb_frag(chan->sdu, skb,
5349 &chan->sdu_last_frag);
5350 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005351
Mat Martineau84084a32011-07-22 14:54:00 -07005352 if (chan->sdu->len != chan->sdu_len)
5353 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005354
Gustavo Padovan80b98022012-05-27 22:27:51 -03005355 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005356
Mat Martineau84084a32011-07-22 14:54:00 -07005357 if (!err) {
5358 /* Reassembly complete */
5359 chan->sdu = NULL;
5360 chan->sdu_last_frag = NULL;
5361 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005362 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005363 break;
5364 }
5365
Mat Martineau84084a32011-07-22 14:54:00 -07005366 if (err) {
5367 kfree_skb(skb);
5368 kfree_skb(chan->sdu);
5369 chan->sdu = NULL;
5370 chan->sdu_last_frag = NULL;
5371 chan->sdu_len = 0;
5372 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005373
Mat Martineau84084a32011-07-22 14:54:00 -07005374 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005375}
5376
Mat Martineau32b32732012-10-23 15:24:11 -07005377static int l2cap_resegment(struct l2cap_chan *chan)
5378{
5379 /* Placeholder */
5380 return 0;
5381}
5382
Mat Martineaue3281402011-07-07 09:39:02 -07005383void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03005384{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005385 u8 event;
5386
5387 if (chan->mode != L2CAP_MODE_ERTM)
5388 return;
5389
5390 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005391 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005392}
5393
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005394static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5395{
Mat Martineau63838722012-05-17 20:53:45 -07005396 int err = 0;
5397 /* Pass sequential frames to l2cap_reassemble_sdu()
5398 * until a gap is encountered.
5399 */
5400
5401 BT_DBG("chan %p", chan);
5402
5403 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5404 struct sk_buff *skb;
5405 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5406 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5407
5408 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5409
5410 if (!skb)
5411 break;
5412
5413 skb_unlink(skb, &chan->srej_q);
5414 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5415 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5416 if (err)
5417 break;
5418 }
5419
5420 if (skb_queue_empty(&chan->srej_q)) {
5421 chan->rx_state = L2CAP_RX_STATE_RECV;
5422 l2cap_send_ack(chan);
5423 }
5424
5425 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005426}
5427
5428static void l2cap_handle_srej(struct l2cap_chan *chan,
5429 struct l2cap_ctrl *control)
5430{
Mat Martineauf80842a2012-05-17 20:53:46 -07005431 struct sk_buff *skb;
5432
5433 BT_DBG("chan %p, control %p", chan, control);
5434
5435 if (control->reqseq == chan->next_tx_seq) {
5436 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005437 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005438 return;
5439 }
5440
5441 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5442
5443 if (skb == NULL) {
5444 BT_DBG("Seq %d not available for retransmission",
5445 control->reqseq);
5446 return;
5447 }
5448
5449 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5450 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005451 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005452 return;
5453 }
5454
5455 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5456
5457 if (control->poll) {
5458 l2cap_pass_to_tx(chan, control);
5459
5460 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5461 l2cap_retransmit(chan, control);
5462 l2cap_ertm_send(chan);
5463
5464 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5465 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5466 chan->srej_save_reqseq = control->reqseq;
5467 }
5468 } else {
5469 l2cap_pass_to_tx_fbit(chan, control);
5470
5471 if (control->final) {
5472 if (chan->srej_save_reqseq != control->reqseq ||
5473 !test_and_clear_bit(CONN_SREJ_ACT,
5474 &chan->conn_state))
5475 l2cap_retransmit(chan, control);
5476 } else {
5477 l2cap_retransmit(chan, control);
5478 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5479 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5480 chan->srej_save_reqseq = control->reqseq;
5481 }
5482 }
5483 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005484}
5485
5486static void l2cap_handle_rej(struct l2cap_chan *chan,
5487 struct l2cap_ctrl *control)
5488{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005489 struct sk_buff *skb;
5490
5491 BT_DBG("chan %p, control %p", chan, control);
5492
5493 if (control->reqseq == chan->next_tx_seq) {
5494 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005495 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005496 return;
5497 }
5498
5499 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5500
5501 if (chan->max_tx && skb &&
5502 bt_cb(skb)->control.retries >= chan->max_tx) {
5503 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005504 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005505 return;
5506 }
5507
5508 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5509
5510 l2cap_pass_to_tx(chan, control);
5511
5512 if (control->final) {
5513 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5514 l2cap_retransmit_all(chan, control);
5515 } else {
5516 l2cap_retransmit_all(chan, control);
5517 l2cap_ertm_send(chan);
5518 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5519 set_bit(CONN_REJ_ACT, &chan->conn_state);
5520 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005521}
5522
Mat Martineau4b51dae92012-05-17 20:53:37 -07005523static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5524{
5525 BT_DBG("chan %p, txseq %d", chan, txseq);
5526
5527 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5528 chan->expected_tx_seq);
5529
5530 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5531 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005532 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005533 /* See notes below regarding "double poll" and
5534 * invalid packets.
5535 */
5536 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5537 BT_DBG("Invalid/Ignore - after SREJ");
5538 return L2CAP_TXSEQ_INVALID_IGNORE;
5539 } else {
5540 BT_DBG("Invalid - in window after SREJ sent");
5541 return L2CAP_TXSEQ_INVALID;
5542 }
5543 }
5544
5545 if (chan->srej_list.head == txseq) {
5546 BT_DBG("Expected SREJ");
5547 return L2CAP_TXSEQ_EXPECTED_SREJ;
5548 }
5549
5550 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5551 BT_DBG("Duplicate SREJ - txseq already stored");
5552 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5553 }
5554
5555 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5556 BT_DBG("Unexpected SREJ - not requested");
5557 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5558 }
5559 }
5560
5561 if (chan->expected_tx_seq == txseq) {
5562 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5563 chan->tx_win) {
5564 BT_DBG("Invalid - txseq outside tx window");
5565 return L2CAP_TXSEQ_INVALID;
5566 } else {
5567 BT_DBG("Expected");
5568 return L2CAP_TXSEQ_EXPECTED;
5569 }
5570 }
5571
5572 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01005573 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005574 BT_DBG("Duplicate - expected_tx_seq later than txseq");
5575 return L2CAP_TXSEQ_DUPLICATE;
5576 }
5577
5578 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
5579 /* A source of invalid packets is a "double poll" condition,
5580 * where delays cause us to send multiple poll packets. If
5581 * the remote stack receives and processes both polls,
5582 * sequence numbers can wrap around in such a way that a
5583 * resent frame has a sequence number that looks like new data
5584 * with a sequence gap. This would trigger an erroneous SREJ
5585 * request.
5586 *
5587 * Fortunately, this is impossible with a tx window that's
5588 * less than half of the maximum sequence number, which allows
5589 * invalid frames to be safely ignored.
5590 *
5591 * With tx window sizes greater than half of the tx window
5592 * maximum, the frame is invalid and cannot be ignored. This
5593 * causes a disconnect.
5594 */
5595
5596 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5597 BT_DBG("Invalid/Ignore - txseq outside tx window");
5598 return L2CAP_TXSEQ_INVALID_IGNORE;
5599 } else {
5600 BT_DBG("Invalid - txseq outside tx window");
5601 return L2CAP_TXSEQ_INVALID;
5602 }
5603 } else {
5604 BT_DBG("Unexpected - txseq indicates missing frames");
5605 return L2CAP_TXSEQ_UNEXPECTED;
5606 }
5607}
5608
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005609static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5610 struct l2cap_ctrl *control,
5611 struct sk_buff *skb, u8 event)
5612{
5613 int err = 0;
5614 bool skb_in_use = 0;
5615
5616 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5617 event);
5618
5619 switch (event) {
5620 case L2CAP_EV_RECV_IFRAME:
5621 switch (l2cap_classify_txseq(chan, control->txseq)) {
5622 case L2CAP_TXSEQ_EXPECTED:
5623 l2cap_pass_to_tx(chan, control);
5624
5625 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5626 BT_DBG("Busy, discarding expected seq %d",
5627 control->txseq);
5628 break;
5629 }
5630
5631 chan->expected_tx_seq = __next_seq(chan,
5632 control->txseq);
5633
5634 chan->buffer_seq = chan->expected_tx_seq;
5635 skb_in_use = 1;
5636
5637 err = l2cap_reassemble_sdu(chan, skb, control);
5638 if (err)
5639 break;
5640
5641 if (control->final) {
5642 if (!test_and_clear_bit(CONN_REJ_ACT,
5643 &chan->conn_state)) {
5644 control->final = 0;
5645 l2cap_retransmit_all(chan, control);
5646 l2cap_ertm_send(chan);
5647 }
5648 }
5649
5650 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5651 l2cap_send_ack(chan);
5652 break;
5653 case L2CAP_TXSEQ_UNEXPECTED:
5654 l2cap_pass_to_tx(chan, control);
5655
5656 /* Can't issue SREJ frames in the local busy state.
5657 * Drop this frame, it will be seen as missing
5658 * when local busy is exited.
5659 */
5660 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5661 BT_DBG("Busy, discarding unexpected seq %d",
5662 control->txseq);
5663 break;
5664 }
5665
5666 /* There was a gap in the sequence, so an SREJ
5667 * must be sent for each missing frame. The
5668 * current frame is stored for later use.
5669 */
5670 skb_queue_tail(&chan->srej_q, skb);
5671 skb_in_use = 1;
5672 BT_DBG("Queued %p (queue len %d)", skb,
5673 skb_queue_len(&chan->srej_q));
5674
5675 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5676 l2cap_seq_list_clear(&chan->srej_list);
5677 l2cap_send_srej(chan, control->txseq);
5678
5679 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5680 break;
5681 case L2CAP_TXSEQ_DUPLICATE:
5682 l2cap_pass_to_tx(chan, control);
5683 break;
5684 case L2CAP_TXSEQ_INVALID_IGNORE:
5685 break;
5686 case L2CAP_TXSEQ_INVALID:
5687 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005688 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005689 break;
5690 }
5691 break;
5692 case L2CAP_EV_RECV_RR:
5693 l2cap_pass_to_tx(chan, control);
5694 if (control->final) {
5695 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5696
Mat Martineaue6a3ee62012-10-23 15:24:22 -07005697 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
5698 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005699 control->final = 0;
5700 l2cap_retransmit_all(chan, control);
5701 }
5702
5703 l2cap_ertm_send(chan);
5704 } else if (control->poll) {
5705 l2cap_send_i_or_rr_or_rnr(chan);
5706 } else {
5707 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5708 &chan->conn_state) &&
5709 chan->unacked_frames)
5710 __set_retrans_timer(chan);
5711
5712 l2cap_ertm_send(chan);
5713 }
5714 break;
5715 case L2CAP_EV_RECV_RNR:
5716 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5717 l2cap_pass_to_tx(chan, control);
5718 if (control && control->poll) {
5719 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5720 l2cap_send_rr_or_rnr(chan, 0);
5721 }
5722 __clear_retrans_timer(chan);
5723 l2cap_seq_list_clear(&chan->retrans_list);
5724 break;
5725 case L2CAP_EV_RECV_REJ:
5726 l2cap_handle_rej(chan, control);
5727 break;
5728 case L2CAP_EV_RECV_SREJ:
5729 l2cap_handle_srej(chan, control);
5730 break;
5731 default:
5732 break;
5733 }
5734
5735 if (skb && !skb_in_use) {
5736 BT_DBG("Freeing %p", skb);
5737 kfree_skb(skb);
5738 }
5739
5740 return err;
5741}
5742
5743static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5744 struct l2cap_ctrl *control,
5745 struct sk_buff *skb, u8 event)
5746{
5747 int err = 0;
5748 u16 txseq = control->txseq;
5749 bool skb_in_use = 0;
5750
5751 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5752 event);
5753
5754 switch (event) {
5755 case L2CAP_EV_RECV_IFRAME:
5756 switch (l2cap_classify_txseq(chan, txseq)) {
5757 case L2CAP_TXSEQ_EXPECTED:
5758 /* Keep frame for reassembly later */
5759 l2cap_pass_to_tx(chan, control);
5760 skb_queue_tail(&chan->srej_q, skb);
5761 skb_in_use = 1;
5762 BT_DBG("Queued %p (queue len %d)", skb,
5763 skb_queue_len(&chan->srej_q));
5764
5765 chan->expected_tx_seq = __next_seq(chan, txseq);
5766 break;
5767 case L2CAP_TXSEQ_EXPECTED_SREJ:
5768 l2cap_seq_list_pop(&chan->srej_list);
5769
5770 l2cap_pass_to_tx(chan, control);
5771 skb_queue_tail(&chan->srej_q, skb);
5772 skb_in_use = 1;
5773 BT_DBG("Queued %p (queue len %d)", skb,
5774 skb_queue_len(&chan->srej_q));
5775
5776 err = l2cap_rx_queued_iframes(chan);
5777 if (err)
5778 break;
5779
5780 break;
5781 case L2CAP_TXSEQ_UNEXPECTED:
5782 /* Got a frame that can't be reassembled yet.
5783 * Save it for later, and send SREJs to cover
5784 * the missing frames.
5785 */
5786 skb_queue_tail(&chan->srej_q, skb);
5787 skb_in_use = 1;
5788 BT_DBG("Queued %p (queue len %d)", skb,
5789 skb_queue_len(&chan->srej_q));
5790
5791 l2cap_pass_to_tx(chan, control);
5792 l2cap_send_srej(chan, control->txseq);
5793 break;
5794 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
5795 /* This frame was requested with an SREJ, but
5796 * some expected retransmitted frames are
5797 * missing. Request retransmission of missing
5798 * SREJ'd frames.
5799 */
5800 skb_queue_tail(&chan->srej_q, skb);
5801 skb_in_use = 1;
5802 BT_DBG("Queued %p (queue len %d)", skb,
5803 skb_queue_len(&chan->srej_q));
5804
5805 l2cap_pass_to_tx(chan, control);
5806 l2cap_send_srej_list(chan, control->txseq);
5807 break;
5808 case L2CAP_TXSEQ_DUPLICATE_SREJ:
5809 /* We've already queued this frame. Drop this copy. */
5810 l2cap_pass_to_tx(chan, control);
5811 break;
5812 case L2CAP_TXSEQ_DUPLICATE:
5813 /* Expecting a later sequence number, so this frame
5814 * was already received. Ignore it completely.
5815 */
5816 break;
5817 case L2CAP_TXSEQ_INVALID_IGNORE:
5818 break;
5819 case L2CAP_TXSEQ_INVALID:
5820 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005821 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005822 break;
5823 }
5824 break;
5825 case L2CAP_EV_RECV_RR:
5826 l2cap_pass_to_tx(chan, control);
5827 if (control->final) {
5828 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5829
5830 if (!test_and_clear_bit(CONN_REJ_ACT,
5831 &chan->conn_state)) {
5832 control->final = 0;
5833 l2cap_retransmit_all(chan, control);
5834 }
5835
5836 l2cap_ertm_send(chan);
5837 } else if (control->poll) {
5838 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5839 &chan->conn_state) &&
5840 chan->unacked_frames) {
5841 __set_retrans_timer(chan);
5842 }
5843
5844 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5845 l2cap_send_srej_tail(chan);
5846 } else {
5847 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5848 &chan->conn_state) &&
5849 chan->unacked_frames)
5850 __set_retrans_timer(chan);
5851
5852 l2cap_send_ack(chan);
5853 }
5854 break;
5855 case L2CAP_EV_RECV_RNR:
5856 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5857 l2cap_pass_to_tx(chan, control);
5858 if (control->poll) {
5859 l2cap_send_srej_tail(chan);
5860 } else {
5861 struct l2cap_ctrl rr_control;
5862 memset(&rr_control, 0, sizeof(rr_control));
5863 rr_control.sframe = 1;
5864 rr_control.super = L2CAP_SUPER_RR;
5865 rr_control.reqseq = chan->buffer_seq;
5866 l2cap_send_sframe(chan, &rr_control);
5867 }
5868
5869 break;
5870 case L2CAP_EV_RECV_REJ:
5871 l2cap_handle_rej(chan, control);
5872 break;
5873 case L2CAP_EV_RECV_SREJ:
5874 l2cap_handle_srej(chan, control);
5875 break;
5876 }
5877
5878 if (skb && !skb_in_use) {
5879 BT_DBG("Freeing %p", skb);
5880 kfree_skb(skb);
5881 }
5882
5883 return err;
5884}
5885
Mat Martineau32b32732012-10-23 15:24:11 -07005886static int l2cap_finish_move(struct l2cap_chan *chan)
5887{
5888 BT_DBG("chan %p", chan);
5889
5890 chan->rx_state = L2CAP_RX_STATE_RECV;
5891
5892 if (chan->hs_hcon)
5893 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
5894 else
5895 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
5896
5897 return l2cap_resegment(chan);
5898}
5899
5900static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
5901 struct l2cap_ctrl *control,
5902 struct sk_buff *skb, u8 event)
5903{
5904 int err;
5905
5906 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5907 event);
5908
5909 if (!control->poll)
5910 return -EPROTO;
5911
5912 l2cap_process_reqseq(chan, control->reqseq);
5913
5914 if (!skb_queue_empty(&chan->tx_q))
5915 chan->tx_send_head = skb_peek(&chan->tx_q);
5916 else
5917 chan->tx_send_head = NULL;
5918
5919 /* Rewind next_tx_seq to the point expected
5920 * by the receiver.
5921 */
5922 chan->next_tx_seq = control->reqseq;
5923 chan->unacked_frames = 0;
5924
5925 err = l2cap_finish_move(chan);
5926 if (err)
5927 return err;
5928
5929 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5930 l2cap_send_i_or_rr_or_rnr(chan);
5931
5932 if (event == L2CAP_EV_RECV_IFRAME)
5933 return -EPROTO;
5934
5935 return l2cap_rx_state_recv(chan, control, NULL, event);
5936}
5937
5938static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
5939 struct l2cap_ctrl *control,
5940 struct sk_buff *skb, u8 event)
5941{
5942 int err;
5943
5944 if (!control->final)
5945 return -EPROTO;
5946
5947 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5948
5949 chan->rx_state = L2CAP_RX_STATE_RECV;
5950 l2cap_process_reqseq(chan, control->reqseq);
5951
5952 if (!skb_queue_empty(&chan->tx_q))
5953 chan->tx_send_head = skb_peek(&chan->tx_q);
5954 else
5955 chan->tx_send_head = NULL;
5956
5957 /* Rewind next_tx_seq to the point expected
5958 * by the receiver.
5959 */
5960 chan->next_tx_seq = control->reqseq;
5961 chan->unacked_frames = 0;
5962
5963 if (chan->hs_hcon)
5964 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
5965 else
5966 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
5967
5968 err = l2cap_resegment(chan);
5969
5970 if (!err)
5971 err = l2cap_rx_state_recv(chan, control, skb, event);
5972
5973 return err;
5974}
5975
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005976static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
5977{
5978 /* Make sure reqseq is for a packet that has been sent but not acked */
5979 u16 unacked;
5980
5981 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
5982 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
5983}
5984
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005985static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5986 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005987{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005988 int err = 0;
5989
5990 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
5991 control, skb, event, chan->rx_state);
5992
5993 if (__valid_reqseq(chan, control->reqseq)) {
5994 switch (chan->rx_state) {
5995 case L2CAP_RX_STATE_RECV:
5996 err = l2cap_rx_state_recv(chan, control, skb, event);
5997 break;
5998 case L2CAP_RX_STATE_SREJ_SENT:
5999 err = l2cap_rx_state_srej_sent(chan, control, skb,
6000 event);
6001 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006002 case L2CAP_RX_STATE_WAIT_P:
6003 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6004 break;
6005 case L2CAP_RX_STATE_WAIT_F:
6006 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6007 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006008 default:
6009 /* shut it down */
6010 break;
6011 }
6012 } else {
6013 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6014 control->reqseq, chan->next_tx_seq,
6015 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006016 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006017 }
6018
6019 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006020}
6021
6022static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6023 struct sk_buff *skb)
6024{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006025 int err = 0;
6026
6027 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6028 chan->rx_state);
6029
6030 if (l2cap_classify_txseq(chan, control->txseq) ==
6031 L2CAP_TXSEQ_EXPECTED) {
6032 l2cap_pass_to_tx(chan, control);
6033
6034 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6035 __next_seq(chan, chan->buffer_seq));
6036
6037 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6038
6039 l2cap_reassemble_sdu(chan, skb, control);
6040 } else {
6041 if (chan->sdu) {
6042 kfree_skb(chan->sdu);
6043 chan->sdu = NULL;
6044 }
6045 chan->sdu_last_frag = NULL;
6046 chan->sdu_len = 0;
6047
6048 if (skb) {
6049 BT_DBG("Freeing %p", skb);
6050 kfree_skb(skb);
6051 }
6052 }
6053
6054 chan->last_acked_seq = control->txseq;
6055 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6056
6057 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006058}
6059
6060static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6061{
6062 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6063 u16 len;
6064 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006065
Mat Martineaub76bbd62012-04-11 10:48:43 -07006066 __unpack_control(chan, skb);
6067
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006068 len = skb->len;
6069
6070 /*
6071 * We can just drop the corrupted I-frame here.
6072 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006073 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006074 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006075 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006076 goto drop;
6077
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006078 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006079 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006080
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006081 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006082 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006083
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006084 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006085 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006086 goto drop;
6087 }
6088
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006089 if (!control->sframe) {
6090 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006091
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006092 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6093 control->sar, control->reqseq, control->final,
6094 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006095
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006096 /* Validate F-bit - F=0 always valid, F=1 only
6097 * valid in TX WAIT_F
6098 */
6099 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006100 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006101
6102 if (chan->mode != L2CAP_MODE_STREAMING) {
6103 event = L2CAP_EV_RECV_IFRAME;
6104 err = l2cap_rx(chan, control, skb, event);
6105 } else {
6106 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006107 }
6108
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006109 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006110 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006111 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006112 const u8 rx_func_to_event[4] = {
6113 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6114 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6115 };
6116
6117 /* Only I-frames are expected in streaming mode */
6118 if (chan->mode == L2CAP_MODE_STREAMING)
6119 goto drop;
6120
6121 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6122 control->reqseq, control->final, control->poll,
6123 control->super);
6124
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006125 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006126 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006127 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006128 goto drop;
6129 }
6130
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006131 /* Validate F and P bits */
6132 if (control->final && (control->poll ||
6133 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6134 goto drop;
6135
6136 event = rx_func_to_event[control->super];
6137 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006138 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006139 }
6140
6141 return 0;
6142
6143drop:
6144 kfree_skb(skb);
6145 return 0;
6146}
6147
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006148static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6149 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006150{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006151 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006152
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006153 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006154 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006155 if (cid == L2CAP_CID_A2MP) {
6156 chan = a2mp_channel_create(conn, skb);
6157 if (!chan) {
6158 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006159 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006160 }
6161
6162 l2cap_chan_lock(chan);
6163 } else {
6164 BT_DBG("unknown cid 0x%4.4x", cid);
6165 /* Drop packet and return */
6166 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006167 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006168 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006169 }
6170
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006171 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006172
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006173 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006174 goto drop;
6175
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006176 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006177 case L2CAP_MODE_BASIC:
6178 /* If socket recv buffers overflows we drop data here
6179 * which is *bad* because L2CAP has to be reliable.
6180 * But we don't have any other choice. L2CAP doesn't
6181 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006182
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006183 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006184 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006185
Gustavo Padovan80b98022012-05-27 22:27:51 -03006186 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006187 goto done;
6188 break;
6189
6190 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006191 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006192 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006193 goto done;
6194
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006195 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006196 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006197 break;
6198 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006199
6200drop:
6201 kfree_skb(skb);
6202
6203done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006204 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006205}
6206
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006207static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6208 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006209{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006210 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006211
Ido Yarivc2287682012-04-20 15:46:07 -03006212 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006213 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006214 goto drop;
6215
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006216 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006217
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006218 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006219 goto drop;
6220
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006221 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006222 goto drop;
6223
Gustavo Padovan80b98022012-05-27 22:27:51 -03006224 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006225 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006226
6227drop:
6228 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006229}
6230
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006231static void l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
6232 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006233{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006234 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006235
Ido Yarivc2287682012-04-20 15:46:07 -03006236 chan = l2cap_global_chan_by_scid(0, cid, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006237 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006238 goto drop;
6239
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006240 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006241
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006242 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006243 goto drop;
6244
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006245 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006246 goto drop;
6247
Gustavo Padovan80b98022012-05-27 22:27:51 -03006248 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006249 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006250
6251drop:
6252 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006253}
6254
Linus Torvalds1da177e2005-04-16 15:20:36 -07006255static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6256{
6257 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006258 u16 cid, len;
6259 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006260
6261 skb_pull(skb, L2CAP_HDR_SIZE);
6262 cid = __le16_to_cpu(lh->cid);
6263 len = __le16_to_cpu(lh->len);
6264
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006265 if (len != skb->len) {
6266 kfree_skb(skb);
6267 return;
6268 }
6269
Linus Torvalds1da177e2005-04-16 15:20:36 -07006270 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6271
6272 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02006273 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006274 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006275 l2cap_sig_channel(conn, skb);
6276 break;
6277
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006278 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006279 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006280 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006281 l2cap_conless_channel(conn, psm, skb);
6282 break;
6283
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006284 case L2CAP_CID_LE_DATA:
6285 l2cap_att_channel(conn, cid, skb);
6286 break;
6287
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006288 case L2CAP_CID_SMP:
6289 if (smp_sig_channel(conn, skb))
6290 l2cap_conn_del(conn->hcon, EACCES);
6291 break;
6292
Linus Torvalds1da177e2005-04-16 15:20:36 -07006293 default:
6294 l2cap_data_channel(conn, cid, skb);
6295 break;
6296 }
6297}
6298
6299/* ---- L2CAP interface with lower layer (HCI) ---- */
6300
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006301int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006302{
6303 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006304 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006305
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006306 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006307
6308 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006309 read_lock(&chan_list_lock);
6310 list_for_each_entry(c, &chan_list, global_l) {
6311 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006312
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006313 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006314 continue;
6315
6316 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006317 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006318 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006319 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006320 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006321 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
6322 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006323 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006324 lm2 |= HCI_LM_MASTER;
6325 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006326 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006327 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006328
6329 return exact ? lm1 : lm2;
6330}
6331
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006332void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006333{
Marcel Holtmann01394182006-07-03 10:02:46 +02006334 struct l2cap_conn *conn;
6335
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006336 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006337
Linus Torvalds1da177e2005-04-16 15:20:36 -07006338 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03006339 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006340 if (conn)
6341 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006342 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006343 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006344 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006345}
6346
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006347int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006348{
6349 struct l2cap_conn *conn = hcon->l2cap_data;
6350
6351 BT_DBG("hcon %p", hcon);
6352
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006353 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006354 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006355 return conn->disc_reason;
6356}
6357
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006358void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006359{
6360 BT_DBG("hcon %p reason %d", hcon, reason);
6361
Joe Perchese1750722011-06-29 18:18:29 -07006362 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006363}
6364
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006365static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006366{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006367 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006368 return;
6369
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006370 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006371 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006372 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006373 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006374 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006375 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006376 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006377 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006378 }
6379}
6380
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006381int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006382{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006383 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006384 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006385
Marcel Holtmann01394182006-07-03 10:02:46 +02006386 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006387 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006388
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006389 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006390
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006391 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306392 if (!status && encrypt)
6393 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006394 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006395 }
6396
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006397 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006398
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006399 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006400 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006401
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006402 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6403 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006404
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006405 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6406 l2cap_chan_unlock(chan);
6407 continue;
6408 }
6409
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006410 if (chan->scid == L2CAP_CID_LE_DATA) {
6411 if (!status && encrypt) {
6412 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006413 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006414 }
6415
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006416 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006417 continue;
6418 }
6419
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006420 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006421 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006422 continue;
6423 }
6424
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006425 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006426 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03006427 struct sock *sk = chan->sk;
6428
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006429 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03006430 sk->sk_state_change(sk);
6431
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006432 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006433 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006434 continue;
6435 }
6436
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006437 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006438 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006439 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006440 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006441 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006442 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006443 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006444 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006445 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006446 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006447
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006448 lock_sock(sk);
6449
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006450 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006451 if (test_bit(BT_SK_DEFER_SETUP,
6452 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006453 res = L2CAP_CR_PEND;
6454 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006455 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006456 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006457 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006458 res = L2CAP_CR_SUCCESS;
6459 stat = L2CAP_CS_NO_INFO;
6460 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006461 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006462 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006463 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006464 res = L2CAP_CR_SEC_BLOCK;
6465 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006466 }
6467
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006468 release_sock(sk);
6469
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006470 rsp.scid = cpu_to_le16(chan->dcid);
6471 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006472 rsp.result = cpu_to_le16(res);
6473 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006474 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006475 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006476
6477 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6478 res == L2CAP_CR_SUCCESS) {
6479 char buf[128];
6480 set_bit(CONF_REQ_SENT, &chan->conf_state);
6481 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6482 L2CAP_CONF_REQ,
6483 l2cap_build_conf_req(chan, buf),
6484 buf);
6485 chan->num_conf_req++;
6486 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006487 }
6488
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006489 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006490 }
6491
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006492 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006493
Linus Torvalds1da177e2005-04-16 15:20:36 -07006494 return 0;
6495}
6496
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006497int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006498{
6499 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006500 struct l2cap_hdr *hdr;
6501 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006502
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006503 /* For AMP controller do not create l2cap conn */
6504 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6505 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006506
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006507 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03006508 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006509
6510 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006511 goto drop;
6512
6513 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6514
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006515 switch (flags) {
6516 case ACL_START:
6517 case ACL_START_NO_FLUSH:
6518 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006519 if (conn->rx_len) {
6520 BT_ERR("Unexpected start frame (len %d)", skb->len);
6521 kfree_skb(conn->rx_skb);
6522 conn->rx_skb = NULL;
6523 conn->rx_len = 0;
6524 l2cap_conn_unreliable(conn, ECOMM);
6525 }
6526
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006527 /* Start fragment always begin with Basic L2CAP header */
6528 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006529 BT_ERR("Frame is too short (len %d)", skb->len);
6530 l2cap_conn_unreliable(conn, ECOMM);
6531 goto drop;
6532 }
6533
6534 hdr = (struct l2cap_hdr *) skb->data;
6535 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6536
6537 if (len == skb->len) {
6538 /* Complete frame received */
6539 l2cap_recv_frame(conn, skb);
6540 return 0;
6541 }
6542
6543 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6544
6545 if (skb->len > len) {
6546 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006547 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006548 l2cap_conn_unreliable(conn, ECOMM);
6549 goto drop;
6550 }
6551
6552 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006553 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006554 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006555 goto drop;
6556
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006557 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006558 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006559 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006560 break;
6561
6562 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006563 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6564
6565 if (!conn->rx_len) {
6566 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6567 l2cap_conn_unreliable(conn, ECOMM);
6568 goto drop;
6569 }
6570
6571 if (skb->len > conn->rx_len) {
6572 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006573 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006574 kfree_skb(conn->rx_skb);
6575 conn->rx_skb = NULL;
6576 conn->rx_len = 0;
6577 l2cap_conn_unreliable(conn, ECOMM);
6578 goto drop;
6579 }
6580
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006581 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006582 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006583 conn->rx_len -= skb->len;
6584
6585 if (!conn->rx_len) {
6586 /* Complete frame received */
6587 l2cap_recv_frame(conn, conn->rx_skb);
6588 conn->rx_skb = NULL;
6589 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006590 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006591 }
6592
6593drop:
6594 kfree_skb(skb);
6595 return 0;
6596}
6597
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006598static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006599{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006600 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006601
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006602 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006603
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006604 list_for_each_entry(c, &chan_list, global_l) {
6605 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006606
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006607 seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
6608 &bt_sk(sk)->src, &bt_sk(sk)->dst,
6609 c->state, __le16_to_cpu(c->psm),
6610 c->scid, c->dcid, c->imtu, c->omtu,
6611 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006612 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006613
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006614 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006615
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006616 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006617}
6618
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006619static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6620{
6621 return single_open(file, l2cap_debugfs_show, inode->i_private);
6622}
6623
6624static const struct file_operations l2cap_debugfs_fops = {
6625 .open = l2cap_debugfs_open,
6626 .read = seq_read,
6627 .llseek = seq_lseek,
6628 .release = single_release,
6629};
6630
6631static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006632
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006633int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006634{
6635 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006636
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006637 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006638 if (err < 0)
6639 return err;
6640
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006641 if (bt_debugfs) {
Gustavo Padovan2d792812012-10-06 10:07:01 +01006642 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6643 NULL, &l2cap_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006644 if (!l2cap_debugfs)
6645 BT_ERR("Failed to create L2CAP debug file");
6646 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006647
Linus Torvalds1da177e2005-04-16 15:20:36 -07006648 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006649}
6650
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006651void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006652{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006653 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006654 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006655}
6656
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006657module_param(disable_ertm, bool, 0644);
6658MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");