blob: 9af3a76844f7cad16f4834f5690ba3bf0e7ab786 [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. Padovan710f9b0a2011-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;
Johan Hedberg9f22398c2013-04-29 19:35:38 +0300507 if (chan->dcid == L2CAP_CID_ATT)
508 chan->scid = L2CAP_CID_ATT;
509 else
510 chan->scid = l2cap_alloc_cid(conn);
Ville Tervob62f3282011-02-10 22:38:50 -0300511 } else {
512 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300513 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300514 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300515 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200516 break;
517
518 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200519 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300520 chan->scid = L2CAP_CID_CONN_LESS;
521 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300522 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200523 break;
524
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300525 case L2CAP_CHAN_CONN_FIX_A2MP:
526 chan->scid = L2CAP_CID_A2MP;
527 chan->dcid = L2CAP_CID_A2MP;
528 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
529 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
530 break;
531
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200532 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200533 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300534 chan->scid = L2CAP_CID_SIGNALING;
535 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300536 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200537 }
538
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300539 chan->local_id = L2CAP_BESTEFFORT_ID;
540 chan->local_stype = L2CAP_SERV_BESTEFFORT;
541 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
542 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
543 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300544 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300545
Ulisses Furquim371fd832011-12-21 20:02:36 -0200546 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300547
Johan Hedberg5ee98912013-04-29 19:35:43 +0300548 hci_conn_hold(conn->hcon);
549
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200550 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200551}
552
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300553void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200554{
555 mutex_lock(&conn->chan_lock);
556 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200557 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200558}
559
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300560void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200561{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300562 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200563
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300564 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200565
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300566 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200567
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900568 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300569 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300570 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200571 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200572
Ulisses Furquim371fd832011-12-21 20:02:36 -0200573 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300574
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300575 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300576
577 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
David Herrmann76a68ba2013-04-06 20:28:37 +0200578 hci_conn_drop(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300579
580 if (mgr && mgr->bredr_chan == chan)
581 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200582 }
583
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200584 if (chan->hs_hchan) {
585 struct hci_chan *hs_hchan = chan->hs_hchan;
586
587 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
588 amp_disconnect_logical_link(hs_hchan);
589 }
590
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100591 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200592
Mat Martineau28270112012-05-17 21:14:09 -0700593 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300594 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300595
Gustavo Padovanee556f62012-05-18 20:22:38 -0300596 switch(chan->mode) {
597 case L2CAP_MODE_BASIC:
598 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300599
Gustavo Padovanee556f62012-05-18 20:22:38 -0300600 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300601 __clear_retrans_timer(chan);
602 __clear_monitor_timer(chan);
603 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300604
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300605 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300606
Mat Martineau3c588192012-04-11 10:48:42 -0700607 l2cap_seq_list_free(&chan->srej_list);
608 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300609
610 /* fall through */
611
612 case L2CAP_MODE_STREAMING:
613 skb_queue_purge(&chan->tx_q);
614 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300615 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300616
617 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200618}
619
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300620void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300621{
622 struct l2cap_conn *conn = chan->conn;
623 struct sock *sk = chan->sk;
624
Gustavo Padovan2d792812012-10-06 10:07:01 +0100625 BT_DBG("chan %p state %s sk %p", chan, state_to_string(chan->state),
626 sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300627
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300628 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300629 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100630 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300631 break;
632
633 case BT_CONNECTED:
634 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300635 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100636 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300637 __set_chan_timer(chan, sk->sk_sndtimeo);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200638 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300639 } else
640 l2cap_chan_del(chan, reason);
641 break;
642
643 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300644 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100645 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300646 struct l2cap_conn_rsp rsp;
647 __u16 result;
648
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300649 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300650 result = L2CAP_CR_SEC_BLOCK;
651 else
652 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300653 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300654
655 rsp.scid = cpu_to_le16(chan->dcid);
656 rsp.dcid = cpu_to_le16(chan->scid);
657 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300658 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300659 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100660 sizeof(rsp), &rsp);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300661 }
662
663 l2cap_chan_del(chan, reason);
664 break;
665
666 case BT_CONNECT:
667 case BT_DISCONN:
668 l2cap_chan_del(chan, reason);
669 break;
670
671 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100672 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300673 break;
674 }
675}
676
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300677static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530678{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300679 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300680 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530681 case BT_SECURITY_HIGH:
682 return HCI_AT_DEDICATED_BONDING_MITM;
683 case BT_SECURITY_MEDIUM:
684 return HCI_AT_DEDICATED_BONDING;
685 default:
686 return HCI_AT_NO_BONDING;
687 }
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +0300688 } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300689 if (chan->sec_level == BT_SECURITY_LOW)
690 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530691
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300692 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530693 return HCI_AT_NO_BONDING_MITM;
694 else
695 return HCI_AT_NO_BONDING;
696 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300697 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530698 case BT_SECURITY_HIGH:
699 return HCI_AT_GENERAL_BONDING_MITM;
700 case BT_SECURITY_MEDIUM:
701 return HCI_AT_GENERAL_BONDING;
702 default:
703 return HCI_AT_NO_BONDING;
704 }
705 }
706}
707
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200708/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200709int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200710{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300711 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100712 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200713
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300714 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100715
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300716 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200717}
718
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200719static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200720{
721 u8 id;
722
723 /* Get next available identificator.
724 * 1 - 128 are used by kernel.
725 * 129 - 199 are reserved.
726 * 200 - 254 are used by utilities like l2ping, etc.
727 */
728
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200729 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200730
731 if (++conn->tx_ident > 128)
732 conn->tx_ident = 1;
733
734 id = conn->tx_ident;
735
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200736 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200737
738 return id;
739}
740
Gustavo Padovan2d792812012-10-06 10:07:01 +0100741static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
742 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200743{
744 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200745 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200746
747 BT_DBG("code 0x%2.2x", code);
748
749 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300750 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200751
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200752 if (lmp_no_flush_capable(conn->hcon->hdev))
753 flags = ACL_START_NO_FLUSH;
754 else
755 flags = ACL_START;
756
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700757 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200758 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700759
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200760 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200761}
762
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700763static bool __chan_is_moving(struct l2cap_chan *chan)
764{
765 return chan->move_state != L2CAP_MOVE_STABLE &&
766 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
767}
768
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200769static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
770{
771 struct hci_conn *hcon = chan->conn->hcon;
772 u16 flags;
773
774 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100775 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200776
Mat Martineaud5f8a752012-10-23 15:24:18 -0700777 if (chan->hs_hcon && !__chan_is_moving(chan)) {
778 if (chan->hs_hchan)
779 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
780 else
781 kfree_skb(skb);
782
783 return;
784 }
785
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200786 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100787 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200788 flags = ACL_START_NO_FLUSH;
789 else
790 flags = ACL_START;
791
792 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
793 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794}
795
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700796static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
797{
798 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
799 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
800
801 if (enh & L2CAP_CTRL_FRAME_TYPE) {
802 /* S-Frame */
803 control->sframe = 1;
804 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
805 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
806
807 control->sar = 0;
808 control->txseq = 0;
809 } else {
810 /* I-Frame */
811 control->sframe = 0;
812 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
813 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
814
815 control->poll = 0;
816 control->super = 0;
817 }
818}
819
820static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
821{
822 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
823 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
824
825 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
826 /* S-Frame */
827 control->sframe = 1;
828 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
829 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
830
831 control->sar = 0;
832 control->txseq = 0;
833 } else {
834 /* I-Frame */
835 control->sframe = 0;
836 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
837 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
838
839 control->poll = 0;
840 control->super = 0;
841 }
842}
843
844static inline void __unpack_control(struct l2cap_chan *chan,
845 struct sk_buff *skb)
846{
847 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
848 __unpack_extended_control(get_unaligned_le32(skb->data),
849 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700850 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700851 } else {
852 __unpack_enhanced_control(get_unaligned_le16(skb->data),
853 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700854 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700855 }
856}
857
858static u32 __pack_extended_control(struct l2cap_ctrl *control)
859{
860 u32 packed;
861
862 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
863 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
864
865 if (control->sframe) {
866 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
867 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
868 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
869 } else {
870 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
871 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
872 }
873
874 return packed;
875}
876
877static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
878{
879 u16 packed;
880
881 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
882 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
883
884 if (control->sframe) {
885 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
886 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
887 packed |= L2CAP_CTRL_FRAME_TYPE;
888 } else {
889 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
890 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
891 }
892
893 return packed;
894}
895
896static inline void __pack_control(struct l2cap_chan *chan,
897 struct l2cap_ctrl *control,
898 struct sk_buff *skb)
899{
900 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
901 put_unaligned_le32(__pack_extended_control(control),
902 skb->data + L2CAP_HDR_SIZE);
903 } else {
904 put_unaligned_le16(__pack_enhanced_control(control),
905 skb->data + L2CAP_HDR_SIZE);
906 }
907}
908
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300909static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
910{
911 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
912 return L2CAP_EXT_HDR_SIZE;
913 else
914 return L2CAP_ENH_HDR_SIZE;
915}
916
Mat Martineaua67d7f62012-05-17 20:53:35 -0700917static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
918 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300919{
920 struct sk_buff *skb;
921 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300922 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300923
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300924 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300925 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300926
Mat Martineaua67d7f62012-05-17 20:53:35 -0700927 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300928
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300929 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700930 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300931
932 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300933 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300934 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300935
Mat Martineaua67d7f62012-05-17 20:53:35 -0700936 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
937 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
938 else
939 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300940
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300941 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700942 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300943 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300944 }
945
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200946 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700947 return skb;
948}
949
950static void l2cap_send_sframe(struct l2cap_chan *chan,
951 struct l2cap_ctrl *control)
952{
953 struct sk_buff *skb;
954 u32 control_field;
955
956 BT_DBG("chan %p, control %p", chan, control);
957
958 if (!control->sframe)
959 return;
960
Mat Martineaub99e13a2012-10-23 15:24:19 -0700961 if (__chan_is_moving(chan))
962 return;
963
Mat Martineaua67d7f62012-05-17 20:53:35 -0700964 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
965 !control->poll)
966 control->final = 1;
967
968 if (control->super == L2CAP_SUPER_RR)
969 clear_bit(CONN_RNR_SENT, &chan->conn_state);
970 else if (control->super == L2CAP_SUPER_RNR)
971 set_bit(CONN_RNR_SENT, &chan->conn_state);
972
973 if (control->super != L2CAP_SUPER_SREJ) {
974 chan->last_acked_seq = control->reqseq;
975 __clear_ack_timer(chan);
976 }
977
978 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
979 control->final, control->poll, control->super);
980
981 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
982 control_field = __pack_extended_control(control);
983 else
984 control_field = __pack_enhanced_control(control);
985
986 skb = l2cap_create_sframe_pdu(chan, control_field);
987 if (!IS_ERR(skb))
988 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300989}
990
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700991static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300992{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700993 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300994
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700995 BT_DBG("chan %p, poll %d", chan, poll);
996
997 memset(&control, 0, sizeof(control));
998 control.sframe = 1;
999 control.poll = poll;
1000
1001 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
1002 control.super = L2CAP_SUPER_RNR;
1003 else
1004 control.super = L2CAP_SUPER_RR;
1005
1006 control.reqseq = chan->buffer_seq;
1007 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001008}
1009
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001010static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001011{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001012 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001013}
1014
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001015static bool __amp_capable(struct l2cap_chan *chan)
1016{
1017 struct l2cap_conn *conn = chan->conn;
1018
1019 if (enable_hs &&
Andrei Emeltchenko5d054162012-11-29 17:46:05 +02001020 hci_amp_capable() &&
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001021 chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED &&
1022 conn->fixed_chan_mask & L2CAP_FC_A2MP)
1023 return true;
1024 else
1025 return false;
1026}
1027
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001028static bool l2cap_check_efs(struct l2cap_chan *chan)
1029{
1030 /* Check EFS parameters */
1031 return true;
1032}
1033
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001034void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001035{
1036 struct l2cap_conn *conn = chan->conn;
1037 struct l2cap_conn_req req;
1038
1039 req.scid = cpu_to_le16(chan->scid);
1040 req.psm = chan->psm;
1041
1042 chan->ident = l2cap_get_ident(conn);
1043
1044 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1045
1046 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1047}
1048
Mat Martineau8eb200b2012-10-23 15:24:17 -07001049static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1050{
1051 struct l2cap_create_chan_req req;
1052 req.scid = cpu_to_le16(chan->scid);
1053 req.psm = chan->psm;
1054 req.amp_id = amp_id;
1055
1056 chan->ident = l2cap_get_ident(chan->conn);
1057
1058 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1059 sizeof(req), &req);
1060}
1061
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001062static void l2cap_move_setup(struct l2cap_chan *chan)
1063{
1064 struct sk_buff *skb;
1065
1066 BT_DBG("chan %p", chan);
1067
1068 if (chan->mode != L2CAP_MODE_ERTM)
1069 return;
1070
1071 __clear_retrans_timer(chan);
1072 __clear_monitor_timer(chan);
1073 __clear_ack_timer(chan);
1074
1075 chan->retry_count = 0;
1076 skb_queue_walk(&chan->tx_q, skb) {
1077 if (bt_cb(skb)->control.retries)
1078 bt_cb(skb)->control.retries = 1;
1079 else
1080 break;
1081 }
1082
1083 chan->expected_tx_seq = chan->buffer_seq;
1084
1085 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1086 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1087 l2cap_seq_list_clear(&chan->retrans_list);
1088 l2cap_seq_list_clear(&chan->srej_list);
1089 skb_queue_purge(&chan->srej_q);
1090
1091 chan->tx_state = L2CAP_TX_STATE_XMIT;
1092 chan->rx_state = L2CAP_RX_STATE_MOVE;
1093
1094 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1095}
1096
Mat Martineau5f3847a2012-10-23 15:24:12 -07001097static void l2cap_move_done(struct l2cap_chan *chan)
1098{
1099 u8 move_role = chan->move_role;
1100 BT_DBG("chan %p", chan);
1101
1102 chan->move_state = L2CAP_MOVE_STABLE;
1103 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1104
1105 if (chan->mode != L2CAP_MODE_ERTM)
1106 return;
1107
1108 switch (move_role) {
1109 case L2CAP_MOVE_ROLE_INITIATOR:
1110 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1111 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1112 break;
1113 case L2CAP_MOVE_ROLE_RESPONDER:
1114 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1115 break;
1116 }
1117}
1118
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001119static void l2cap_chan_ready(struct l2cap_chan *chan)
1120{
Mat Martineau28270112012-05-17 21:14:09 -07001121 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001122 chan->conf_state = 0;
1123 __clear_chan_timer(chan);
1124
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001125 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001126
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001127 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001128}
1129
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001130static void l2cap_start_connection(struct l2cap_chan *chan)
1131{
1132 if (__amp_capable(chan)) {
1133 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1134 a2mp_discover_amp(chan);
1135 } else {
1136 l2cap_send_conn_req(chan);
1137 }
1138}
1139
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001140static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001141{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001142 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001143
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001144 if (conn->hcon->type == LE_LINK) {
1145 l2cap_chan_ready(chan);
1146 return;
1147 }
1148
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001149 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001150 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1151 return;
1152
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001153 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001154 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001155 l2cap_start_connection(chan);
1156 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001157 } else {
1158 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001159 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001160
1161 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1162 conn->info_ident = l2cap_get_ident(conn);
1163
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001164 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001165
Gustavo Padovan2d792812012-10-06 10:07:01 +01001166 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1167 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001168 }
1169}
1170
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001171static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1172{
1173 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001174 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001175 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1176
1177 switch (mode) {
1178 case L2CAP_MODE_ERTM:
1179 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1180 case L2CAP_MODE_STREAMING:
1181 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1182 default:
1183 return 0x00;
1184 }
1185}
1186
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001187static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001188{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001189 struct sock *sk = chan->sk;
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001190 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001191 struct l2cap_disconn_req req;
1192
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001193 if (!conn)
1194 return;
1195
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001196 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001197 __clear_retrans_timer(chan);
1198 __clear_monitor_timer(chan);
1199 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001200 }
1201
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001202 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001203 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001204 return;
1205 }
1206
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001207 req.dcid = cpu_to_le16(chan->dcid);
1208 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001209 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1210 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001211
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001212 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001213 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001214 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001215 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001216}
1217
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001219static void l2cap_conn_start(struct l2cap_conn *conn)
1220{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001221 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001222
1223 BT_DBG("conn %p", conn);
1224
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001225 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001226
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001227 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001228 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001229
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001230 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001231
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001232 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001233 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001234 continue;
1235 }
1236
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001237 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001238 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001239 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001240 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001241 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001242 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001243
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001244 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001245 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001246 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001247 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001248 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001249 continue;
1250 }
1251
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001252 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001253
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001254 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001255 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001256 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001257 rsp.scid = cpu_to_le16(chan->dcid);
1258 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001259
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001260 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001261 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001262 if (test_bit(BT_SK_DEFER_SETUP,
1263 &bt_sk(sk)->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001264 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1265 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001266 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001267
1268 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001269 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001270 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1271 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001272 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001273 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001274 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001275 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1276 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001277 }
1278
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001279 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001280 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001281
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001282 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001283 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001284 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001285 continue;
1286 }
1287
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001288 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001289 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001290 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001291 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001292 }
1293
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001294 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001295 }
1296
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001297 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001298}
1299
Ido Yarivc2287682012-04-20 15:46:07 -03001300/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001301 * Returns closest match, locked.
1302 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001303static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001304 bdaddr_t *src,
1305 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001306{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001307 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001308
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001309 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001310
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001311 list_for_each_entry(c, &chan_list, global_l) {
1312 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001313
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001314 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001315 continue;
1316
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001317 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001318 int src_match, dst_match;
1319 int src_any, dst_any;
1320
Ville Tervob62f3282011-02-10 22:38:50 -03001321 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001322 src_match = !bacmp(&bt_sk(sk)->src, src);
1323 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1324 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001325 read_unlock(&chan_list_lock);
1326 return c;
1327 }
Ville Tervob62f3282011-02-10 22:38:50 -03001328
1329 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001330 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1331 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1332 if ((src_match && dst_any) || (src_any && dst_match) ||
1333 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001334 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001335 }
1336 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001337
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001338 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001339
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001340 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001341}
1342
1343static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1344{
Johan Hedberg60bac182013-04-29 19:35:41 +03001345 struct sock *parent;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001346 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001347
1348 BT_DBG("");
1349
1350 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001351 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Ido Yarivc2287682012-04-20 15:46:07 -03001352 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001353 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001354 return;
1355
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001356 /* Client ATT sockets should override the server one */
1357 if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
1358 return;
1359
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001360 parent = pchan->sk;
1361
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001362 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001363
Gustavo Padovan80b98022012-05-27 22:27:51 -03001364 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001365 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001366 goto clean;
1367
Johan Hedberg9f22398c2013-04-29 19:35:38 +03001368 chan->dcid = L2CAP_CID_ATT;
1369
Johan Hedberg60bac182013-04-29 19:35:41 +03001370 bacpy(&bt_sk(chan->sk)->src, conn->src);
1371 bacpy(&bt_sk(chan->sk)->dst, conn->dst);
Ville Tervob62f3282011-02-10 22:38:50 -03001372
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001373 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001374
Ville Tervob62f3282011-02-10 22:38:50 -03001375clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001376 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001377}
1378
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001379static void l2cap_conn_ready(struct l2cap_conn *conn)
1380{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001381 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001382 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001383
1384 BT_DBG("conn %p", conn);
1385
Johan Hedbergd8729922013-04-29 19:35:39 +03001386 /* For outgoing pairing which doesn't necessarily have an
1387 * associated socket (e.g. mgmt_pair_device).
1388 */
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001389 if (hcon->out && hcon->type == LE_LINK)
1390 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001391
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001392 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001393
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001394 if (hcon->type == LE_LINK)
1395 l2cap_le_conn_ready(conn);
1396
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001397 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001398
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001399 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001400
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001401 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1402 l2cap_chan_unlock(chan);
1403 continue;
1404 }
1405
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001406 if (hcon->type == LE_LINK) {
1407 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001408 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001409
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001410 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001411 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001412 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001413 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001414 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001415 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001416 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001417
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001418 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001419 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001420
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001421 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001422 }
1423
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001424 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001425}
1426
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001427/* Notify sockets that we cannot guaranty reliability anymore */
1428static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1429{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001430 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001431
1432 BT_DBG("conn %p", conn);
1433
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001434 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001435
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001436 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001437 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001438 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001439 }
1440
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001441 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001442}
1443
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001444static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001445{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001446 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001447 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001448
Marcel Holtmann984947d2009-02-06 23:35:19 +01001449 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001450 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001451
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001452 l2cap_conn_start(conn);
1453}
1454
David Herrmann2c8e1412013-04-06 20:28:45 +02001455/*
1456 * l2cap_user
1457 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1458 * callback is called during registration. The ->remove callback is called
1459 * during unregistration.
1460 * An l2cap_user object can either be explicitly unregistered or when the
1461 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1462 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1463 * External modules must own a reference to the l2cap_conn object if they intend
1464 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1465 * any time if they don't.
1466 */
1467
1468int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1469{
1470 struct hci_dev *hdev = conn->hcon->hdev;
1471 int ret;
1472
1473 /* We need to check whether l2cap_conn is registered. If it is not, we
1474 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1475 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1476 * relies on the parent hci_conn object to be locked. This itself relies
1477 * on the hci_dev object to be locked. So we must lock the hci device
1478 * here, too. */
1479
1480 hci_dev_lock(hdev);
1481
1482 if (user->list.next || user->list.prev) {
1483 ret = -EINVAL;
1484 goto out_unlock;
1485 }
1486
1487 /* conn->hchan is NULL after l2cap_conn_del() was called */
1488 if (!conn->hchan) {
1489 ret = -ENODEV;
1490 goto out_unlock;
1491 }
1492
1493 ret = user->probe(conn, user);
1494 if (ret)
1495 goto out_unlock;
1496
1497 list_add(&user->list, &conn->users);
1498 ret = 0;
1499
1500out_unlock:
1501 hci_dev_unlock(hdev);
1502 return ret;
1503}
1504EXPORT_SYMBOL(l2cap_register_user);
1505
1506void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1507{
1508 struct hci_dev *hdev = conn->hcon->hdev;
1509
1510 hci_dev_lock(hdev);
1511
1512 if (!user->list.next || !user->list.prev)
1513 goto out_unlock;
1514
1515 list_del(&user->list);
1516 user->list.next = NULL;
1517 user->list.prev = NULL;
1518 user->remove(conn, user);
1519
1520out_unlock:
1521 hci_dev_unlock(hdev);
1522}
1523EXPORT_SYMBOL(l2cap_unregister_user);
1524
1525static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1526{
1527 struct l2cap_user *user;
1528
1529 while (!list_empty(&conn->users)) {
1530 user = list_first_entry(&conn->users, struct l2cap_user, list);
1531 list_del(&user->list);
1532 user->list.next = NULL;
1533 user->list.prev = NULL;
1534 user->remove(conn, user);
1535 }
1536}
1537
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001538static void l2cap_conn_del(struct hci_conn *hcon, int err)
1539{
1540 struct l2cap_conn *conn = hcon->l2cap_data;
1541 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001542
1543 if (!conn)
1544 return;
1545
1546 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1547
1548 kfree_skb(conn->rx_skb);
1549
David Herrmann2c8e1412013-04-06 20:28:45 +02001550 l2cap_unregister_all_users(conn);
1551
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001552 mutex_lock(&conn->chan_lock);
1553
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001554 /* Kill channels */
1555 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001556 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001557 l2cap_chan_lock(chan);
1558
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001559 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001560
1561 l2cap_chan_unlock(chan);
1562
Gustavo Padovan80b98022012-05-27 22:27:51 -03001563 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001564 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001565 }
1566
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001567 mutex_unlock(&conn->chan_lock);
1568
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001569 hci_chan_del(conn->hchan);
1570
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001571 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001572 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001573
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001574 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001575 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001576 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001577 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001578
1579 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001580 conn->hchan = NULL;
1581 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001582}
1583
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001584static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001585{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001586 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001587 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001588
Johan Hedbergd06cc412012-06-06 18:44:11 +08001589 BT_DBG("conn %p", conn);
1590
1591 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1592 smp_chan_destroy(conn);
1593 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1594 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001595}
1596
Claudio Takahasibaf43252013-04-11 13:55:50 -03001597static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598{
Marcel Holtmann01394182006-07-03 10:02:46 +02001599 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001600 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601
Claudio Takahasibaf43252013-04-11 13:55:50 -03001602 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603 return conn;
1604
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001605 hchan = hci_chan_create(hcon);
1606 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001609 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001610 if (!conn) {
1611 hci_chan_del(hchan);
1612 return NULL;
1613 }
1614
David Herrmann9c903e32013-04-06 20:28:44 +02001615 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001616 hcon->l2cap_data = conn;
1617 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001618 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001619 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001621 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001622
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001623 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001624 case LE_LINK:
1625 if (hcon->hdev->le_mtu) {
1626 conn->mtu = hcon->hdev->le_mtu;
1627 break;
1628 }
1629 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001630 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001631 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001632 break;
1633 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001634
Linus Torvalds1da177e2005-04-16 15:20:36 -07001635 conn->src = &hcon->hdev->bdaddr;
1636 conn->dst = &hcon->dst;
1637
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001638 conn->feat_mask = 0;
1639
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001641 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001642
1643 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001644 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001645
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001646 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001647 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001648 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001649 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001650
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001651 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001652
Linus Torvalds1da177e2005-04-16 15:20:36 -07001653 return conn;
1654}
1655
David Herrmann9c903e32013-04-06 20:28:44 +02001656static void l2cap_conn_free(struct kref *ref)
1657{
1658 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1659
1660 hci_conn_put(conn->hcon);
1661 kfree(conn);
1662}
1663
1664void l2cap_conn_get(struct l2cap_conn *conn)
1665{
1666 kref_get(&conn->ref);
1667}
1668EXPORT_SYMBOL(l2cap_conn_get);
1669
1670void l2cap_conn_put(struct l2cap_conn *conn)
1671{
1672 kref_put(&conn->ref, l2cap_conn_free);
1673}
1674EXPORT_SYMBOL(l2cap_conn_put);
1675
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677
Ido Yarivc2287682012-04-20 15:46:07 -03001678/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 * Returns closest match.
1680 */
Ido Yarivc2287682012-04-20 15:46:07 -03001681static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1682 bdaddr_t *src,
1683 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001685 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001687 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001688
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001689 list_for_each_entry(c, &chan_list, global_l) {
1690 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001691
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001692 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693 continue;
1694
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001695 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001696 int src_match, dst_match;
1697 int src_any, dst_any;
1698
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001700 src_match = !bacmp(&bt_sk(sk)->src, src);
1701 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1702 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001703 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001704 return c;
1705 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706
1707 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001708 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1709 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1710 if ((src_match && dst_any) || (src_any && dst_match) ||
1711 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001712 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713 }
1714 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001716 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001717
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001718 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719}
1720
Andre Guedes8e9f9892012-04-24 21:02:55 -03001721int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1722 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001724 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726 struct l2cap_conn *conn;
1727 struct hci_conn *hcon;
1728 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001729 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001730 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001732 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301733 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001735 hdev = hci_get_route(dst, src);
1736 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 return -EHOSTUNREACH;
1738
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001739 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001741 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001742
1743 /* PSM must be odd and lsb of upper byte must be 0 */
1744 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001745 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001746 err = -EINVAL;
1747 goto done;
1748 }
1749
1750 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1751 err = -EINVAL;
1752 goto done;
1753 }
1754
1755 switch (chan->mode) {
1756 case L2CAP_MODE_BASIC:
1757 break;
1758 case L2CAP_MODE_ERTM:
1759 case L2CAP_MODE_STREAMING:
1760 if (!disable_ertm)
1761 break;
1762 /* fall through */
1763 default:
1764 err = -ENOTSUPP;
1765 goto done;
1766 }
1767
Gustavo Padovan0797e012012-05-27 22:27:54 -03001768 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001769 case BT_CONNECT:
1770 case BT_CONNECT2:
1771 case BT_CONFIG:
1772 /* Already connecting */
1773 err = 0;
1774 goto done;
1775
1776 case BT_CONNECTED:
1777 /* Already connected */
1778 err = -EISCONN;
1779 goto done;
1780
1781 case BT_OPEN:
1782 case BT_BOUND:
1783 /* Can connect */
1784 break;
1785
1786 default:
1787 err = -EBADFD;
1788 goto done;
1789 }
1790
1791 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001792 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001793 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001794 release_sock(sk);
1795
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001796 chan->psm = psm;
1797 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001799 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001800
Johan Hedbergf224ca52013-04-29 19:35:36 +03001801 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001802 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001803 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001804 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001805 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001806 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001807
Ville Tervo30e76272011-02-22 16:10:53 -03001808 if (IS_ERR(hcon)) {
1809 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001811 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812
Claudio Takahasibaf43252013-04-11 13:55:50 -03001813 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001815 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001816 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 goto done;
1818 }
1819
Johan Hedberg141d5702013-04-29 19:35:37 +03001820 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1821 hci_conn_drop(hcon);
1822 err = -EBUSY;
1823 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001824 }
1825
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826 /* Update source addr of the socket */
1827 bacpy(src, conn->src);
1828
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001829 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001830 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001831 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001832
Johan Hedberg5ee98912013-04-29 19:35:43 +03001833 /* l2cap_chan_add takes its own ref so we can drop this one */
1834 hci_conn_drop(hcon);
1835
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001836 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001837 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838
1839 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001840 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001841 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001842 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001843 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001844 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001845 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846 }
1847
Ville Tervo30e76272011-02-22 16:10:53 -03001848 err = 0;
1849
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001851 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001852 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853 hci_dev_put(hdev);
1854 return err;
1855}
1856
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001857int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001858{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001859 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001860 DECLARE_WAITQUEUE(wait, current);
1861 int err = 0;
1862 int timeo = HZ/5;
1863
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001864 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001865 set_current_state(TASK_INTERRUPTIBLE);
1866 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001867 if (!timeo)
1868 timeo = HZ/5;
1869
1870 if (signal_pending(current)) {
1871 err = sock_intr_errno(timeo);
1872 break;
1873 }
1874
1875 release_sock(sk);
1876 timeo = schedule_timeout(timeo);
1877 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001878 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001879
1880 err = sock_error(sk);
1881 if (err)
1882 break;
1883 }
1884 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001885 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001886 return err;
1887}
1888
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001889static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001890{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001891 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001892 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001893
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001894 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001895
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001896 l2cap_chan_lock(chan);
1897
Mat Martineau80909e02012-05-17 20:53:50 -07001898 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001899 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001900 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001901 return;
1902 }
1903
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001904 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001905
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001906 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001907 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001908}
1909
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001910static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001911{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001912 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001913 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001914
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001915 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001916
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001917 l2cap_chan_lock(chan);
1918
Mat Martineau80909e02012-05-17 20:53:50 -07001919 if (!chan->conn) {
1920 l2cap_chan_unlock(chan);
1921 l2cap_chan_put(chan);
1922 return;
1923 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001924
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001925 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001926 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001927 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001928}
1929
Gustavo Padovand6603662012-05-21 13:58:22 -03001930static void l2cap_streaming_send(struct l2cap_chan *chan,
1931 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001932{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001933 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001934 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001935
Mat Martineau37339372012-05-17 20:53:33 -07001936 BT_DBG("chan %p, skbs %p", chan, skbs);
1937
Mat Martineaub99e13a2012-10-23 15:24:19 -07001938 if (__chan_is_moving(chan))
1939 return;
1940
Mat Martineau37339372012-05-17 20:53:33 -07001941 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1942
1943 while (!skb_queue_empty(&chan->tx_q)) {
1944
1945 skb = skb_dequeue(&chan->tx_q);
1946
1947 bt_cb(skb)->control.retries = 1;
1948 control = &bt_cb(skb)->control;
1949
1950 control->reqseq = 0;
1951 control->txseq = chan->next_tx_seq;
1952
1953 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001954
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001955 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001956 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1957 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001958 }
1959
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001960 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001961
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001962 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001963
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001964 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001965 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001966 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001967}
1968
Szymon Janc67c9e842011-07-28 16:24:33 +02001969static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001970{
1971 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001972 struct l2cap_ctrl *control;
1973 int sent = 0;
1974
1975 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001976
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001977 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001978 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001979
Mat Martineau94122bb2012-05-02 09:42:02 -07001980 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1981 return 0;
1982
Mat Martineaub99e13a2012-10-23 15:24:19 -07001983 if (__chan_is_moving(chan))
1984 return 0;
1985
Mat Martineau18a48e72012-05-17 20:53:34 -07001986 while (chan->tx_send_head &&
1987 chan->unacked_frames < chan->remote_tx_win &&
1988 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001989
Mat Martineau18a48e72012-05-17 20:53:34 -07001990 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001991
Mat Martineau18a48e72012-05-17 20:53:34 -07001992 bt_cb(skb)->control.retries = 1;
1993 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001994
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001995 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001996 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001997
Mat Martineau18a48e72012-05-17 20:53:34 -07001998 control->reqseq = chan->buffer_seq;
1999 chan->last_acked_seq = chan->buffer_seq;
2000 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002001
Mat Martineau18a48e72012-05-17 20:53:34 -07002002 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002003
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002004 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07002005 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2006 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002007 }
2008
Mat Martineau18a48e72012-05-17 20:53:34 -07002009 /* Clone after data has been modified. Data is assumed to be
2010 read-only (for locking purposes) on cloned sk_buffs.
2011 */
2012 tx_skb = skb_clone(skb, GFP_KERNEL);
2013
2014 if (!tx_skb)
2015 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002016
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002017 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002018
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002019 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002020 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002021 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002022 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002023
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002024 if (skb_queue_is_last(&chan->tx_q, skb))
2025 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002026 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002027 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002028
2029 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002030 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002031 }
2032
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002033 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2034 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002035
2036 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002037}
2038
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002039static void l2cap_ertm_resend(struct l2cap_chan *chan)
2040{
2041 struct l2cap_ctrl control;
2042 struct sk_buff *skb;
2043 struct sk_buff *tx_skb;
2044 u16 seq;
2045
2046 BT_DBG("chan %p", chan);
2047
2048 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2049 return;
2050
Mat Martineaub99e13a2012-10-23 15:24:19 -07002051 if (__chan_is_moving(chan))
2052 return;
2053
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002054 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2055 seq = l2cap_seq_list_pop(&chan->retrans_list);
2056
2057 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2058 if (!skb) {
2059 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002060 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002061 continue;
2062 }
2063
2064 bt_cb(skb)->control.retries++;
2065 control = bt_cb(skb)->control;
2066
2067 if (chan->max_tx != 0 &&
2068 bt_cb(skb)->control.retries > chan->max_tx) {
2069 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002070 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002071 l2cap_seq_list_clear(&chan->retrans_list);
2072 break;
2073 }
2074
2075 control.reqseq = chan->buffer_seq;
2076 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2077 control.final = 1;
2078 else
2079 control.final = 0;
2080
2081 if (skb_cloned(skb)) {
2082 /* Cloned sk_buffs are read-only, so we need a
2083 * writeable copy
2084 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002085 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002086 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002087 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002088 }
2089
2090 if (!tx_skb) {
2091 l2cap_seq_list_clear(&chan->retrans_list);
2092 break;
2093 }
2094
2095 /* Update skb contents */
2096 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2097 put_unaligned_le32(__pack_extended_control(&control),
2098 tx_skb->data + L2CAP_HDR_SIZE);
2099 } else {
2100 put_unaligned_le16(__pack_enhanced_control(&control),
2101 tx_skb->data + L2CAP_HDR_SIZE);
2102 }
2103
2104 if (chan->fcs == L2CAP_FCS_CRC16) {
2105 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2106 put_unaligned_le16(fcs, skb_put(tx_skb,
2107 L2CAP_FCS_SIZE));
2108 }
2109
2110 l2cap_do_send(chan, tx_skb);
2111
2112 BT_DBG("Resent txseq %d", control.txseq);
2113
2114 chan->last_acked_seq = chan->buffer_seq;
2115 }
2116}
2117
Mat Martineauf80842a2012-05-17 20:53:46 -07002118static void l2cap_retransmit(struct l2cap_chan *chan,
2119 struct l2cap_ctrl *control)
2120{
2121 BT_DBG("chan %p, control %p", chan, control);
2122
2123 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2124 l2cap_ertm_resend(chan);
2125}
2126
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002127static void l2cap_retransmit_all(struct l2cap_chan *chan,
2128 struct l2cap_ctrl *control)
2129{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002130 struct sk_buff *skb;
2131
2132 BT_DBG("chan %p, control %p", chan, control);
2133
2134 if (control->poll)
2135 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2136
2137 l2cap_seq_list_clear(&chan->retrans_list);
2138
2139 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2140 return;
2141
2142 if (chan->unacked_frames) {
2143 skb_queue_walk(&chan->tx_q, skb) {
2144 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002145 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002146 break;
2147 }
2148
2149 skb_queue_walk_from(&chan->tx_q, skb) {
2150 if (skb == chan->tx_send_head)
2151 break;
2152
2153 l2cap_seq_list_append(&chan->retrans_list,
2154 bt_cb(skb)->control.txseq);
2155 }
2156
2157 l2cap_ertm_resend(chan);
2158 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002159}
2160
Szymon Jancb17e73b2012-01-11 10:59:47 +01002161static void l2cap_send_ack(struct l2cap_chan *chan)
2162{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002163 struct l2cap_ctrl control;
2164 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2165 chan->last_acked_seq);
2166 int threshold;
2167
2168 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2169 chan, chan->last_acked_seq, chan->buffer_seq);
2170
2171 memset(&control, 0, sizeof(control));
2172 control.sframe = 1;
2173
2174 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2175 chan->rx_state == L2CAP_RX_STATE_RECV) {
2176 __clear_ack_timer(chan);
2177 control.super = L2CAP_SUPER_RNR;
2178 control.reqseq = chan->buffer_seq;
2179 l2cap_send_sframe(chan, &control);
2180 } else {
2181 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2182 l2cap_ertm_send(chan);
2183 /* If any i-frames were sent, they included an ack */
2184 if (chan->buffer_seq == chan->last_acked_seq)
2185 frames_to_ack = 0;
2186 }
2187
Mat Martineauc20f8e32012-07-10 05:47:07 -07002188 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002189 * Calculate without mul or div
2190 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002191 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002192 threshold += threshold << 1;
2193 threshold >>= 2;
2194
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002195 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002196 threshold);
2197
2198 if (frames_to_ack >= threshold) {
2199 __clear_ack_timer(chan);
2200 control.super = L2CAP_SUPER_RR;
2201 control.reqseq = chan->buffer_seq;
2202 l2cap_send_sframe(chan, &control);
2203 frames_to_ack = 0;
2204 }
2205
2206 if (frames_to_ack)
2207 __set_ack_timer(chan);
2208 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002209}
2210
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002211static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2212 struct msghdr *msg, int len,
2213 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002214{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002215 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002216 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002217 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002218
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002219 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002220 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002221
2222 sent += count;
2223 len -= count;
2224
2225 /* Continuation fragments (no L2CAP header) */
2226 frag = &skb_shinfo(skb)->frag_list;
2227 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002228 struct sk_buff *tmp;
2229
Linus Torvalds1da177e2005-04-16 15:20:36 -07002230 count = min_t(unsigned int, conn->mtu, len);
2231
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002232 tmp = chan->ops->alloc_skb(chan, count,
2233 msg->msg_flags & MSG_DONTWAIT);
2234 if (IS_ERR(tmp))
2235 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002236
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002237 *frag = tmp;
2238
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002239 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2240 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002241
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002242 (*frag)->priority = skb->priority;
2243
Linus Torvalds1da177e2005-04-16 15:20:36 -07002244 sent += count;
2245 len -= count;
2246
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002247 skb->len += (*frag)->len;
2248 skb->data_len += (*frag)->len;
2249
Linus Torvalds1da177e2005-04-16 15:20:36 -07002250 frag = &(*frag)->next;
2251 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252
2253 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002254}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002256static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002257 struct msghdr *msg, size_t len,
2258 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002259{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002260 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002261 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002262 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002263 struct l2cap_hdr *lh;
2264
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002265 BT_DBG("chan %p len %zu priority %u", chan, len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002266
2267 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002268
2269 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002270 msg->msg_flags & MSG_DONTWAIT);
2271 if (IS_ERR(skb))
2272 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002273
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002274 skb->priority = priority;
2275
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002276 /* Create L2CAP header */
2277 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002278 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002279 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
2280 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002281
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002282 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002283 if (unlikely(err < 0)) {
2284 kfree_skb(skb);
2285 return ERR_PTR(err);
2286 }
2287 return skb;
2288}
2289
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002290static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002291 struct msghdr *msg, size_t len,
2292 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002293{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002294 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002295 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002296 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002297 struct l2cap_hdr *lh;
2298
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002299 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002300
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002301 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002302
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002303 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002304 msg->msg_flags & MSG_DONTWAIT);
2305 if (IS_ERR(skb))
2306 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002307
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002308 skb->priority = priority;
2309
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002310 /* Create L2CAP header */
2311 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002312 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002313 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002314
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002315 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002316 if (unlikely(err < 0)) {
2317 kfree_skb(skb);
2318 return ERR_PTR(err);
2319 }
2320 return skb;
2321}
2322
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002323static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002324 struct msghdr *msg, size_t len,
2325 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002326{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002327 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002328 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002329 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002330 struct l2cap_hdr *lh;
2331
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002332 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002333
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002334 if (!conn)
2335 return ERR_PTR(-ENOTCONN);
2336
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002337 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002338
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002339 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002340 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002341
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002342 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002343 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002344
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002345 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002346
2347 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002348 msg->msg_flags & MSG_DONTWAIT);
2349 if (IS_ERR(skb))
2350 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002351
2352 /* Create L2CAP header */
2353 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002354 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002355 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002356
Mat Martineau18a48e72012-05-17 20:53:34 -07002357 /* Control header is populated later */
2358 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2359 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2360 else
2361 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002362
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002363 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002364 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002365
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002366 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002367 if (unlikely(err < 0)) {
2368 kfree_skb(skb);
2369 return ERR_PTR(err);
2370 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002371
Mat Martineau18a48e72012-05-17 20:53:34 -07002372 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002373 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002374 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002375}
2376
Mat Martineau94122bb2012-05-02 09:42:02 -07002377static int l2cap_segment_sdu(struct l2cap_chan *chan,
2378 struct sk_buff_head *seg_queue,
2379 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002380{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002381 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002382 u16 sdu_len;
2383 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002384 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002385
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002386 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002387
Mat Martineau94122bb2012-05-02 09:42:02 -07002388 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2389 * so fragmented skbs are not used. The HCI layer's handling
2390 * of fragmented skbs is not compatible with ERTM's queueing.
2391 */
2392
2393 /* PDU size is derived from the HCI MTU */
2394 pdu_len = chan->conn->mtu;
2395
Mat Martineaua5495742012-10-23 15:24:21 -07002396 /* Constrain PDU size for BR/EDR connections */
2397 if (!chan->hs_hcon)
2398 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002399
2400 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002401 if (chan->fcs)
2402 pdu_len -= L2CAP_FCS_SIZE;
2403
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002404 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002405
2406 /* Remote device may have requested smaller PDUs */
2407 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2408
2409 if (len <= pdu_len) {
2410 sar = L2CAP_SAR_UNSEGMENTED;
2411 sdu_len = 0;
2412 pdu_len = len;
2413 } else {
2414 sar = L2CAP_SAR_START;
2415 sdu_len = len;
2416 pdu_len -= L2CAP_SDULEN_SIZE;
2417 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002418
2419 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002420 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002421
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002422 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002423 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002424 return PTR_ERR(skb);
2425 }
2426
Mat Martineau94122bb2012-05-02 09:42:02 -07002427 bt_cb(skb)->control.sar = sar;
2428 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002429
Mat Martineau94122bb2012-05-02 09:42:02 -07002430 len -= pdu_len;
2431 if (sdu_len) {
2432 sdu_len = 0;
2433 pdu_len += L2CAP_SDULEN_SIZE;
2434 }
2435
2436 if (len <= pdu_len) {
2437 sar = L2CAP_SAR_END;
2438 pdu_len = len;
2439 } else {
2440 sar = L2CAP_SAR_CONTINUE;
2441 }
2442 }
2443
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002444 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002445}
2446
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002447int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002448 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002449{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002450 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002451 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002452 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002453
2454 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002455 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002456 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002457 if (IS_ERR(skb))
2458 return PTR_ERR(skb);
2459
2460 l2cap_do_send(chan, skb);
2461 return len;
2462 }
2463
2464 switch (chan->mode) {
2465 case L2CAP_MODE_BASIC:
2466 /* Check outgoing MTU */
2467 if (len > chan->omtu)
2468 return -EMSGSIZE;
2469
2470 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002471 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002472 if (IS_ERR(skb))
2473 return PTR_ERR(skb);
2474
2475 l2cap_do_send(chan, skb);
2476 err = len;
2477 break;
2478
2479 case L2CAP_MODE_ERTM:
2480 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002481 /* Check outgoing MTU */
2482 if (len > chan->omtu) {
2483 err = -EMSGSIZE;
2484 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002485 }
2486
Mat Martineau94122bb2012-05-02 09:42:02 -07002487 __skb_queue_head_init(&seg_queue);
2488
2489 /* Do segmentation before calling in to the state machine,
2490 * since it's possible to block while waiting for memory
2491 * allocation.
2492 */
2493 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2494
2495 /* The channel could have been closed while segmenting,
2496 * check that it is still connected.
2497 */
2498 if (chan->state != BT_CONNECTED) {
2499 __skb_queue_purge(&seg_queue);
2500 err = -ENOTCONN;
2501 }
2502
2503 if (err)
2504 break;
2505
Mat Martineau37339372012-05-17 20:53:33 -07002506 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002507 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002508 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002509 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002510
Gustavo Padovand6603662012-05-21 13:58:22 -03002511 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002512
Mat Martineau94122bb2012-05-02 09:42:02 -07002513 /* If the skbs were not queued for sending, they'll still be in
2514 * seg_queue and need to be purged.
2515 */
2516 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002517 break;
2518
2519 default:
2520 BT_DBG("bad state %1.1x", chan->mode);
2521 err = -EBADFD;
2522 }
2523
2524 return err;
2525}
2526
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002527static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2528{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002529 struct l2cap_ctrl control;
2530 u16 seq;
2531
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002532 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002533
2534 memset(&control, 0, sizeof(control));
2535 control.sframe = 1;
2536 control.super = L2CAP_SUPER_SREJ;
2537
2538 for (seq = chan->expected_tx_seq; seq != txseq;
2539 seq = __next_seq(chan, seq)) {
2540 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2541 control.reqseq = seq;
2542 l2cap_send_sframe(chan, &control);
2543 l2cap_seq_list_append(&chan->srej_list, seq);
2544 }
2545 }
2546
2547 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002548}
2549
2550static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2551{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002552 struct l2cap_ctrl control;
2553
2554 BT_DBG("chan %p", chan);
2555
2556 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2557 return;
2558
2559 memset(&control, 0, sizeof(control));
2560 control.sframe = 1;
2561 control.super = L2CAP_SUPER_SREJ;
2562 control.reqseq = chan->srej_list.tail;
2563 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002564}
2565
2566static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2567{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002568 struct l2cap_ctrl control;
2569 u16 initial_head;
2570 u16 seq;
2571
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002572 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002573
2574 memset(&control, 0, sizeof(control));
2575 control.sframe = 1;
2576 control.super = L2CAP_SUPER_SREJ;
2577
2578 /* Capture initial list head to allow only one pass through the list. */
2579 initial_head = chan->srej_list.head;
2580
2581 do {
2582 seq = l2cap_seq_list_pop(&chan->srej_list);
2583 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2584 break;
2585
2586 control.reqseq = seq;
2587 l2cap_send_sframe(chan, &control);
2588 l2cap_seq_list_append(&chan->srej_list, seq);
2589 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002590}
2591
Mat Martineau608bcc62012-05-17 20:53:32 -07002592static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2593{
2594 struct sk_buff *acked_skb;
2595 u16 ackseq;
2596
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002597 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002598
2599 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2600 return;
2601
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002602 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002603 chan->expected_ack_seq, chan->unacked_frames);
2604
2605 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2606 ackseq = __next_seq(chan, ackseq)) {
2607
2608 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2609 if (acked_skb) {
2610 skb_unlink(acked_skb, &chan->tx_q);
2611 kfree_skb(acked_skb);
2612 chan->unacked_frames--;
2613 }
2614 }
2615
2616 chan->expected_ack_seq = reqseq;
2617
2618 if (chan->unacked_frames == 0)
2619 __clear_retrans_timer(chan);
2620
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002621 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002622}
2623
2624static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2625{
2626 BT_DBG("chan %p", chan);
2627
2628 chan->expected_tx_seq = chan->buffer_seq;
2629 l2cap_seq_list_clear(&chan->srej_list);
2630 skb_queue_purge(&chan->srej_q);
2631 chan->rx_state = L2CAP_RX_STATE_RECV;
2632}
2633
Gustavo Padovand6603662012-05-21 13:58:22 -03002634static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2635 struct l2cap_ctrl *control,
2636 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002637{
Mat Martineau608bcc62012-05-17 20:53:32 -07002638 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2639 event);
2640
2641 switch (event) {
2642 case L2CAP_EV_DATA_REQUEST:
2643 if (chan->tx_send_head == NULL)
2644 chan->tx_send_head = skb_peek(skbs);
2645
2646 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2647 l2cap_ertm_send(chan);
2648 break;
2649 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2650 BT_DBG("Enter LOCAL_BUSY");
2651 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2652
2653 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2654 /* The SREJ_SENT state must be aborted if we are to
2655 * enter the LOCAL_BUSY state.
2656 */
2657 l2cap_abort_rx_srej_sent(chan);
2658 }
2659
2660 l2cap_send_ack(chan);
2661
2662 break;
2663 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2664 BT_DBG("Exit LOCAL_BUSY");
2665 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2666
2667 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2668 struct l2cap_ctrl local_control;
2669
2670 memset(&local_control, 0, sizeof(local_control));
2671 local_control.sframe = 1;
2672 local_control.super = L2CAP_SUPER_RR;
2673 local_control.poll = 1;
2674 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002675 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002676
2677 chan->retry_count = 1;
2678 __set_monitor_timer(chan);
2679 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2680 }
2681 break;
2682 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2683 l2cap_process_reqseq(chan, control->reqseq);
2684 break;
2685 case L2CAP_EV_EXPLICIT_POLL:
2686 l2cap_send_rr_or_rnr(chan, 1);
2687 chan->retry_count = 1;
2688 __set_monitor_timer(chan);
2689 __clear_ack_timer(chan);
2690 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2691 break;
2692 case L2CAP_EV_RETRANS_TO:
2693 l2cap_send_rr_or_rnr(chan, 1);
2694 chan->retry_count = 1;
2695 __set_monitor_timer(chan);
2696 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2697 break;
2698 case L2CAP_EV_RECV_FBIT:
2699 /* Nothing to process */
2700 break;
2701 default:
2702 break;
2703 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002704}
2705
Gustavo Padovand6603662012-05-21 13:58:22 -03002706static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2707 struct l2cap_ctrl *control,
2708 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002709{
Mat Martineau608bcc62012-05-17 20:53:32 -07002710 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2711 event);
2712
2713 switch (event) {
2714 case L2CAP_EV_DATA_REQUEST:
2715 if (chan->tx_send_head == NULL)
2716 chan->tx_send_head = skb_peek(skbs);
2717 /* Queue data, but don't send. */
2718 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2719 break;
2720 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2721 BT_DBG("Enter LOCAL_BUSY");
2722 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2723
2724 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2725 /* The SREJ_SENT state must be aborted if we are to
2726 * enter the LOCAL_BUSY state.
2727 */
2728 l2cap_abort_rx_srej_sent(chan);
2729 }
2730
2731 l2cap_send_ack(chan);
2732
2733 break;
2734 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2735 BT_DBG("Exit LOCAL_BUSY");
2736 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2737
2738 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2739 struct l2cap_ctrl local_control;
2740 memset(&local_control, 0, sizeof(local_control));
2741 local_control.sframe = 1;
2742 local_control.super = L2CAP_SUPER_RR;
2743 local_control.poll = 1;
2744 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002745 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002746
2747 chan->retry_count = 1;
2748 __set_monitor_timer(chan);
2749 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2750 }
2751 break;
2752 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2753 l2cap_process_reqseq(chan, control->reqseq);
2754
2755 /* Fall through */
2756
2757 case L2CAP_EV_RECV_FBIT:
2758 if (control && control->final) {
2759 __clear_monitor_timer(chan);
2760 if (chan->unacked_frames > 0)
2761 __set_retrans_timer(chan);
2762 chan->retry_count = 0;
2763 chan->tx_state = L2CAP_TX_STATE_XMIT;
2764 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2765 }
2766 break;
2767 case L2CAP_EV_EXPLICIT_POLL:
2768 /* Ignore */
2769 break;
2770 case L2CAP_EV_MONITOR_TO:
2771 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2772 l2cap_send_rr_or_rnr(chan, 1);
2773 __set_monitor_timer(chan);
2774 chan->retry_count++;
2775 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002776 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002777 }
2778 break;
2779 default:
2780 break;
2781 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002782}
2783
Gustavo Padovand6603662012-05-21 13:58:22 -03002784static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2785 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002786{
Mat Martineau608bcc62012-05-17 20:53:32 -07002787 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2788 chan, control, skbs, event, chan->tx_state);
2789
2790 switch (chan->tx_state) {
2791 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002792 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002793 break;
2794 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002795 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002796 break;
2797 default:
2798 /* Ignore event */
2799 break;
2800 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002801}
2802
Mat Martineau4b51dae92012-05-17 20:53:37 -07002803static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2804 struct l2cap_ctrl *control)
2805{
2806 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002807 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002808}
2809
Mat Martineauf80842a2012-05-17 20:53:46 -07002810static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2811 struct l2cap_ctrl *control)
2812{
2813 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002814 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002815}
2816
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817/* Copy frame to all raw sockets on that connection */
2818static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2819{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002820 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002821 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002822
2823 BT_DBG("conn %p", conn);
2824
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002825 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002826
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002827 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002828 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002829 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002830 continue;
2831
2832 /* Don't send frame to the socket it came from */
2833 if (skb->sk == sk)
2834 continue;
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002835 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002836 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002837 continue;
2838
Gustavo Padovan80b98022012-05-27 22:27:51 -03002839 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002840 kfree_skb(nskb);
2841 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002842
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002843 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002844}
2845
2846/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002847static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2848 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002849{
2850 struct sk_buff *skb, **frag;
2851 struct l2cap_cmd_hdr *cmd;
2852 struct l2cap_hdr *lh;
2853 int len, count;
2854
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002855 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2856 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002857
Anderson Lizardo300b9622013-06-02 16:30:40 -04002858 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2859 return NULL;
2860
Linus Torvalds1da177e2005-04-16 15:20:36 -07002861 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2862 count = min_t(unsigned int, conn->mtu, len);
2863
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002864 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002865 if (!skb)
2866 return NULL;
2867
2868 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002869 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002870
2871 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002872 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002873 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002874 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002875
2876 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2877 cmd->code = code;
2878 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002879 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002880
2881 if (dlen) {
2882 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2883 memcpy(skb_put(skb, count), data, count);
2884 data += count;
2885 }
2886
2887 len -= skb->len;
2888
2889 /* Continuation fragments (no L2CAP header) */
2890 frag = &skb_shinfo(skb)->frag_list;
2891 while (len) {
2892 count = min_t(unsigned int, conn->mtu, len);
2893
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002894 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002895 if (!*frag)
2896 goto fail;
2897
2898 memcpy(skb_put(*frag, count), data, count);
2899
2900 len -= count;
2901 data += count;
2902
2903 frag = &(*frag)->next;
2904 }
2905
2906 return skb;
2907
2908fail:
2909 kfree_skb(skb);
2910 return NULL;
2911}
2912
Gustavo Padovan2d792812012-10-06 10:07:01 +01002913static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2914 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002915{
2916 struct l2cap_conf_opt *opt = *ptr;
2917 int len;
2918
2919 len = L2CAP_CONF_OPT_SIZE + opt->len;
2920 *ptr += len;
2921
2922 *type = opt->type;
2923 *olen = opt->len;
2924
2925 switch (opt->len) {
2926 case 1:
2927 *val = *((u8 *) opt->val);
2928 break;
2929
2930 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002931 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002932 break;
2933
2934 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002935 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002936 break;
2937
2938 default:
2939 *val = (unsigned long) opt->val;
2940 break;
2941 }
2942
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002943 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002944 return len;
2945}
2946
Linus Torvalds1da177e2005-04-16 15:20:36 -07002947static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2948{
2949 struct l2cap_conf_opt *opt = *ptr;
2950
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002951 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002952
2953 opt->type = type;
2954 opt->len = len;
2955
2956 switch (len) {
2957 case 1:
2958 *((u8 *) opt->val) = val;
2959 break;
2960
2961 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002962 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002963 break;
2964
2965 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002966 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002967 break;
2968
2969 default:
2970 memcpy(opt->val, (void *) val, len);
2971 break;
2972 }
2973
2974 *ptr += L2CAP_CONF_OPT_SIZE + len;
2975}
2976
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002977static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2978{
2979 struct l2cap_conf_efs efs;
2980
Szymon Janc1ec918c2011-11-16 09:32:21 +01002981 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002982 case L2CAP_MODE_ERTM:
2983 efs.id = chan->local_id;
2984 efs.stype = chan->local_stype;
2985 efs.msdu = cpu_to_le16(chan->local_msdu);
2986 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002987 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002988 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002989 break;
2990
2991 case L2CAP_MODE_STREAMING:
2992 efs.id = 1;
2993 efs.stype = L2CAP_SERV_BESTEFFORT;
2994 efs.msdu = cpu_to_le16(chan->local_msdu);
2995 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2996 efs.acc_lat = 0;
2997 efs.flush_to = 0;
2998 break;
2999
3000 default:
3001 return;
3002 }
3003
3004 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003005 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003006}
3007
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003008static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003009{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003010 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003011 ack_timer.work);
3012 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003013
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003014 BT_DBG("chan %p", chan);
3015
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003016 l2cap_chan_lock(chan);
3017
Mat Martineau03625202012-05-17 20:53:51 -07003018 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3019 chan->last_acked_seq);
3020
3021 if (frames_to_ack)
3022 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003023
3024 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003025 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003026}
3027
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003028int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003029{
Mat Martineau3c588192012-04-11 10:48:42 -07003030 int err;
3031
Mat Martineau105bdf92012-04-27 16:50:48 -07003032 chan->next_tx_seq = 0;
3033 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003034 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003035 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003036 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003037 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003038 chan->last_acked_seq = 0;
3039 chan->sdu = NULL;
3040 chan->sdu_last_frag = NULL;
3041 chan->sdu_len = 0;
3042
Mat Martineaud34c34f2012-05-14 14:49:27 -07003043 skb_queue_head_init(&chan->tx_q);
3044
Mat Martineau08333282012-10-23 15:24:06 -07003045 chan->local_amp_id = 0;
3046 chan->move_id = 0;
3047 chan->move_state = L2CAP_MOVE_STABLE;
3048 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3049
Mat Martineau105bdf92012-04-27 16:50:48 -07003050 if (chan->mode != L2CAP_MODE_ERTM)
3051 return 0;
3052
3053 chan->rx_state = L2CAP_RX_STATE_RECV;
3054 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003055
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003056 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3057 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3058 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003059
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003060 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003061
Mat Martineau3c588192012-04-11 10:48:42 -07003062 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3063 if (err < 0)
3064 return err;
3065
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003066 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3067 if (err < 0)
3068 l2cap_seq_list_free(&chan->srej_list);
3069
3070 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003071}
3072
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003073static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3074{
3075 switch (mode) {
3076 case L2CAP_MODE_STREAMING:
3077 case L2CAP_MODE_ERTM:
3078 if (l2cap_mode_supported(mode, remote_feat_mask))
3079 return mode;
3080 /* fall through */
3081 default:
3082 return L2CAP_MODE_BASIC;
3083 }
3084}
3085
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003086static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
3087{
3088 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
3089}
3090
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003091static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
3092{
3093 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
3094}
3095
Mat Martineau36c86c82012-10-23 15:24:20 -07003096static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3097 struct l2cap_conf_rfc *rfc)
3098{
3099 if (chan->local_amp_id && chan->hs_hcon) {
3100 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3101
3102 /* Class 1 devices have must have ERTM timeouts
3103 * exceeding the Link Supervision Timeout. The
3104 * default Link Supervision Timeout for AMP
3105 * controllers is 10 seconds.
3106 *
3107 * Class 1 devices use 0xffffffff for their
3108 * best-effort flush timeout, so the clamping logic
3109 * will result in a timeout that meets the above
3110 * requirement. ERTM timeouts are 16-bit values, so
3111 * the maximum timeout is 65.535 seconds.
3112 */
3113
3114 /* Convert timeout to milliseconds and round */
3115 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3116
3117 /* This is the recommended formula for class 2 devices
3118 * that start ERTM timers when packets are sent to the
3119 * controller.
3120 */
3121 ertm_to = 3 * ertm_to + 500;
3122
3123 if (ertm_to > 0xffff)
3124 ertm_to = 0xffff;
3125
3126 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3127 rfc->monitor_timeout = rfc->retrans_timeout;
3128 } else {
3129 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3130 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3131 }
3132}
3133
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003134static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3135{
3136 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003137 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003138 /* use extended control field */
3139 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003140 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3141 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003142 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003143 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003144 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3145 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003146 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003147}
3148
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003149static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003150{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003151 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003152 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003153 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003154 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003155
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003156 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003157
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003158 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003159 goto done;
3160
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003161 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003162 case L2CAP_MODE_STREAMING:
3163 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003164 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003165 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003166
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003167 if (__l2cap_efs_supported(chan))
3168 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3169
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003170 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003171 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003172 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003173 break;
3174 }
3175
3176done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003177 if (chan->imtu != L2CAP_DEFAULT_MTU)
3178 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003179
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003180 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003181 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003182 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003183 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003184 break;
3185
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003186 rfc.mode = L2CAP_MODE_BASIC;
3187 rfc.txwin_size = 0;
3188 rfc.max_transmit = 0;
3189 rfc.retrans_timeout = 0;
3190 rfc.monitor_timeout = 0;
3191 rfc.max_pdu_size = 0;
3192
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003193 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003194 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003195 break;
3196
3197 case L2CAP_MODE_ERTM:
3198 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003199 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003200
3201 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003202
3203 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003204 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3205 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003206 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003207
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003208 l2cap_txwin_setup(chan);
3209
3210 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003211 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003212
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003213 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003214 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003215
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003216 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3217 l2cap_add_opt_efs(&ptr, chan);
3218
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003219 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3220 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003221 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003222
3223 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3224 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003225 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003226 chan->fcs = L2CAP_FCS_NONE;
3227 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3228 chan->fcs);
3229 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003230 break;
3231
3232 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003233 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003234 rfc.mode = L2CAP_MODE_STREAMING;
3235 rfc.txwin_size = 0;
3236 rfc.max_transmit = 0;
3237 rfc.retrans_timeout = 0;
3238 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003239
3240 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003241 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3242 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003243 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003244
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003245 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003246 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003247
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003248 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3249 l2cap_add_opt_efs(&ptr, chan);
3250
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003251 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3252 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003253 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003254 chan->fcs = L2CAP_FCS_NONE;
3255 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3256 chan->fcs);
3257 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003258 break;
3259 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003260
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003261 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003262 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003263
3264 return ptr - data;
3265}
3266
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003267static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003268{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003269 struct l2cap_conf_rsp *rsp = data;
3270 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003271 void *req = chan->conf_req;
3272 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003273 int type, hint, olen;
3274 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003275 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003276 struct l2cap_conf_efs efs;
3277 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003278 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003279 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003280 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003281
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003282 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003283
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003284 while (len >= L2CAP_CONF_OPT_SIZE) {
3285 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003286
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003287 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003288 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003289
3290 switch (type) {
3291 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003292 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003293 break;
3294
3295 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003296 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003297 break;
3298
3299 case L2CAP_CONF_QOS:
3300 break;
3301
Marcel Holtmann6464f352007-10-20 13:39:51 +02003302 case L2CAP_CONF_RFC:
3303 if (olen == sizeof(rfc))
3304 memcpy(&rfc, (void *) val, olen);
3305 break;
3306
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003307 case L2CAP_CONF_FCS:
3308 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003309 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003310 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003311
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003312 case L2CAP_CONF_EFS:
3313 remote_efs = 1;
3314 if (olen == sizeof(efs))
3315 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003316 break;
3317
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003318 case L2CAP_CONF_EWS:
3319 if (!enable_hs)
3320 return -ECONNREFUSED;
3321
3322 set_bit(FLAG_EXT_CTRL, &chan->flags);
3323 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003324 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003325 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003326 break;
3327
3328 default:
3329 if (hint)
3330 break;
3331
3332 result = L2CAP_CONF_UNKNOWN;
3333 *((u8 *) ptr++) = type;
3334 break;
3335 }
3336 }
3337
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003338 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003339 goto done;
3340
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003341 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003342 case L2CAP_MODE_STREAMING:
3343 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003344 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003345 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003346 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003347 break;
3348 }
3349
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003350 if (remote_efs) {
3351 if (__l2cap_efs_supported(chan))
3352 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3353 else
3354 return -ECONNREFUSED;
3355 }
3356
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003357 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003358 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003359
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003360 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003361 }
3362
3363done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003364 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003365 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003366 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003367
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003368 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003369 return -ECONNREFUSED;
3370
Gustavo Padovan2d792812012-10-06 10:07:01 +01003371 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3372 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003373 }
3374
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003375 if (result == L2CAP_CONF_SUCCESS) {
3376 /* Configure output options and let the other side know
3377 * which ones we don't like. */
3378
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003379 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3380 result = L2CAP_CONF_UNACCEPT;
3381 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003382 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003383 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003384 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003385 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003386
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003387 if (remote_efs) {
3388 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003389 efs.stype != L2CAP_SERV_NOTRAFIC &&
3390 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003391
3392 result = L2CAP_CONF_UNACCEPT;
3393
3394 if (chan->num_conf_req >= 1)
3395 return -ECONNREFUSED;
3396
3397 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003398 sizeof(efs),
3399 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003400 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003401 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003402 result = L2CAP_CONF_PENDING;
3403 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003404 }
3405 }
3406
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003407 switch (rfc.mode) {
3408 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003409 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003410 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003411 break;
3412
3413 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003414 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3415 chan->remote_tx_win = rfc.txwin_size;
3416 else
3417 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3418
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003419 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003420
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003421 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003422 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3423 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003424 rfc.max_pdu_size = cpu_to_le16(size);
3425 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003426
Mat Martineau36c86c82012-10-23 15:24:20 -07003427 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003428
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003429 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003430
3431 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003432 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003433
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003434 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3435 chan->remote_id = efs.id;
3436 chan->remote_stype = efs.stype;
3437 chan->remote_msdu = le16_to_cpu(efs.msdu);
3438 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003439 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003440 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003441 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003442 chan->remote_sdu_itime =
3443 le32_to_cpu(efs.sdu_itime);
3444 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003445 sizeof(efs),
3446 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003447 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003448 break;
3449
3450 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003451 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003452 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3453 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003454 rfc.max_pdu_size = cpu_to_le16(size);
3455 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003456
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003457 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003458
Gustavo Padovan2d792812012-10-06 10:07:01 +01003459 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3460 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003461
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003462 break;
3463
3464 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003465 result = L2CAP_CONF_UNACCEPT;
3466
3467 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003468 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003469 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003470
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003471 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003472 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003473 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003474 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003475 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003476 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003477
3478 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003479}
3480
Gustavo Padovan2d792812012-10-06 10:07:01 +01003481static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3482 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003483{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003484 struct l2cap_conf_req *req = data;
3485 void *ptr = req->data;
3486 int type, olen;
3487 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003488 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003489 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003490
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003491 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003492
3493 while (len >= L2CAP_CONF_OPT_SIZE) {
3494 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3495
3496 switch (type) {
3497 case L2CAP_CONF_MTU:
3498 if (val < L2CAP_DEFAULT_MIN_MTU) {
3499 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003500 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003501 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003502 chan->imtu = val;
3503 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003504 break;
3505
3506 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003507 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003508 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003509 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003510 break;
3511
3512 case L2CAP_CONF_RFC:
3513 if (olen == sizeof(rfc))
3514 memcpy(&rfc, (void *)val, olen);
3515
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003516 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003517 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003518 return -ECONNREFUSED;
3519
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003520 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003521
3522 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003523 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003524 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003525
3526 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003527 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003528 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003529 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003530 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003531
3532 case L2CAP_CONF_EFS:
3533 if (olen == sizeof(efs))
3534 memcpy(&efs, (void *)val, olen);
3535
3536 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003537 efs.stype != L2CAP_SERV_NOTRAFIC &&
3538 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003539 return -ECONNREFUSED;
3540
Gustavo Padovan2d792812012-10-06 10:07:01 +01003541 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3542 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003543 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003544
3545 case L2CAP_CONF_FCS:
3546 if (*result == L2CAP_CONF_PENDING)
3547 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003548 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003549 &chan->conf_state);
3550 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003551 }
3552 }
3553
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003554 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003555 return -ECONNREFUSED;
3556
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003557 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003558
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003559 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003560 switch (rfc.mode) {
3561 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003562 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3563 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3564 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003565 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3566 chan->ack_win = min_t(u16, chan->ack_win,
3567 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003568
3569 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3570 chan->local_msdu = le16_to_cpu(efs.msdu);
3571 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003572 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003573 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3574 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003575 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003576 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003577 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003578
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003579 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003580 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003581 }
3582 }
3583
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003584 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003585 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003586
3587 return ptr - data;
3588}
3589
Gustavo Padovan2d792812012-10-06 10:07:01 +01003590static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3591 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003592{
3593 struct l2cap_conf_rsp *rsp = data;
3594 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003595
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003596 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003597
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003598 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003599 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003600 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003601
3602 return ptr - data;
3603}
3604
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003605void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003606{
3607 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003608 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003609 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003610 u8 rsp_code;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003611
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003612 rsp.scid = cpu_to_le16(chan->dcid);
3613 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003614 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3615 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003616
3617 if (chan->hs_hcon)
3618 rsp_code = L2CAP_CREATE_CHAN_RSP;
3619 else
3620 rsp_code = L2CAP_CONN_RSP;
3621
3622 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3623
3624 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003625
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003626 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003627 return;
3628
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003629 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003630 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003631 chan->num_conf_req++;
3632}
3633
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003634static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003635{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003636 int type, olen;
3637 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003638 /* Use sane default values in case a misbehaving remote device
3639 * did not send an RFC or extended window size option.
3640 */
3641 u16 txwin_ext = chan->ack_win;
3642 struct l2cap_conf_rfc rfc = {
3643 .mode = chan->mode,
3644 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3645 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3646 .max_pdu_size = cpu_to_le16(chan->imtu),
3647 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3648 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003649
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003650 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003651
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003652 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003653 return;
3654
3655 while (len >= L2CAP_CONF_OPT_SIZE) {
3656 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3657
Mat Martineauc20f8e32012-07-10 05:47:07 -07003658 switch (type) {
3659 case L2CAP_CONF_RFC:
3660 if (olen == sizeof(rfc))
3661 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003662 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003663 case L2CAP_CONF_EWS:
3664 txwin_ext = val;
3665 break;
3666 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003667 }
3668
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003669 switch (rfc.mode) {
3670 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003671 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3672 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003673 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3674 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3675 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3676 else
3677 chan->ack_win = min_t(u16, chan->ack_win,
3678 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003679 break;
3680 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003681 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003682 }
3683}
3684
Gustavo Padovan2d792812012-10-06 10:07:01 +01003685static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003686 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3687 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003688{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003689 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003690
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003691 if (cmd_len < sizeof(*rej))
3692 return -EPROTO;
3693
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003694 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003695 return 0;
3696
3697 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003698 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003699 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003700
3701 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003702 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003703
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003704 l2cap_conn_start(conn);
3705 }
3706
3707 return 0;
3708}
3709
Mat Martineau17009152012-10-23 15:24:07 -07003710static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3711 struct l2cap_cmd_hdr *cmd,
3712 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003713{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003714 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3715 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003716 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003717 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003718 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003719
3720 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003721 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003722
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003723 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003724
3725 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003726 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003727 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003728 result = L2CAP_CR_BAD_PSM;
3729 goto sendresp;
3730 }
3731
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003732 parent = pchan->sk;
3733
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003734 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003735 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003736
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003737 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003738 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003739 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003740 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003741 result = L2CAP_CR_SEC_BLOCK;
3742 goto response;
3743 }
3744
Linus Torvalds1da177e2005-04-16 15:20:36 -07003745 result = L2CAP_CR_NO_MEM;
3746
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003747 /* Check if we already have channel with that dcid */
3748 if (__l2cap_get_chan_by_dcid(conn, scid))
3749 goto response;
3750
Gustavo Padovan80b98022012-05-27 22:27:51 -03003751 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003752 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003753 goto response;
3754
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003755 sk = chan->sk;
3756
Linus Torvalds1da177e2005-04-16 15:20:36 -07003757 bacpy(&bt_sk(sk)->src, conn->src);
3758 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003759 chan->psm = psm;
3760 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003761 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003762
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003763 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003764
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003765 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003766
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003767 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003768
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003769 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003770
Marcel Holtmann984947d2009-02-06 23:35:19 +01003771 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003772 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003773 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003774 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003775 result = L2CAP_CR_PEND;
3776 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003777 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003778 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003779 /* Force pending result for AMP controllers.
3780 * The connection will succeed after the
3781 * physical link is up.
3782 */
3783 if (amp_id) {
3784 __l2cap_state_change(chan, BT_CONNECT2);
3785 result = L2CAP_CR_PEND;
3786 } else {
3787 __l2cap_state_change(chan, BT_CONFIG);
3788 result = L2CAP_CR_SUCCESS;
3789 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003790 status = L2CAP_CS_NO_INFO;
3791 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003792 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003793 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003794 result = L2CAP_CR_PEND;
3795 status = L2CAP_CS_AUTHEN_PEND;
3796 }
3797 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003798 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003799 result = L2CAP_CR_PEND;
3800 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003801 }
3802
Linus Torvalds1da177e2005-04-16 15:20:36 -07003803response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003804 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003805 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003806
3807sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003808 rsp.scid = cpu_to_le16(scid);
3809 rsp.dcid = cpu_to_le16(dcid);
3810 rsp.result = cpu_to_le16(result);
3811 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003812 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003813
3814 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3815 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003816 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003817
3818 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3819 conn->info_ident = l2cap_get_ident(conn);
3820
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003821 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003822
Gustavo Padovan2d792812012-10-06 10:07:01 +01003823 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3824 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003825 }
3826
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003827 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003828 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003829 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003830 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003831 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003832 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003833 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003834 }
Mat Martineau17009152012-10-23 15:24:07 -07003835
3836 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003837}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003838
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003839static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003840 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003841{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303842 struct hci_dev *hdev = conn->hcon->hdev;
3843 struct hci_conn *hcon = conn->hcon;
3844
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003845 if (cmd_len < sizeof(struct l2cap_conn_req))
3846 return -EPROTO;
3847
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303848 hci_dev_lock(hdev);
3849 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3850 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3851 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3852 hcon->dst_type, 0, NULL, 0,
3853 hcon->dev_class);
3854 hci_dev_unlock(hdev);
3855
Gustavo Padovan300229f2012-10-12 19:40:40 +08003856 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003857 return 0;
3858}
3859
Mat Martineau5909cf32012-10-23 15:24:08 -07003860static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003861 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3862 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003863{
3864 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3865 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003866 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003867 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003868 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003869
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003870 if (cmd_len < sizeof(*rsp))
3871 return -EPROTO;
3872
Linus Torvalds1da177e2005-04-16 15:20:36 -07003873 scid = __le16_to_cpu(rsp->scid);
3874 dcid = __le16_to_cpu(rsp->dcid);
3875 result = __le16_to_cpu(rsp->result);
3876 status = __le16_to_cpu(rsp->status);
3877
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003878 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 +01003879 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003880
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003881 mutex_lock(&conn->chan_lock);
3882
Linus Torvalds1da177e2005-04-16 15:20:36 -07003883 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003884 chan = __l2cap_get_chan_by_scid(conn, scid);
3885 if (!chan) {
3886 err = -EFAULT;
3887 goto unlock;
3888 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003889 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003890 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3891 if (!chan) {
3892 err = -EFAULT;
3893 goto unlock;
3894 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003895 }
3896
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003897 err = 0;
3898
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003899 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003900
Linus Torvalds1da177e2005-04-16 15:20:36 -07003901 switch (result) {
3902 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003903 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003904 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003905 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003906 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003907
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003908 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003909 break;
3910
Linus Torvalds1da177e2005-04-16 15:20:36 -07003911 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003912 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003913 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003914 break;
3915
3916 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003917 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003918 break;
3919
3920 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003921 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003922 break;
3923 }
3924
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003925 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003926
3927unlock:
3928 mutex_unlock(&conn->chan_lock);
3929
3930 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003931}
3932
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003933static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003934{
3935 /* FCS is enabled only in ERTM or streaming mode, if one or both
3936 * sides request it.
3937 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003938 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003939 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003940 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003941 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003942}
3943
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003944static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3945 u8 ident, u16 flags)
3946{
3947 struct l2cap_conn *conn = chan->conn;
3948
3949 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3950 flags);
3951
3952 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3953 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3954
3955 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
3956 l2cap_build_conf_rsp(chan, data,
3957 L2CAP_CONF_SUCCESS, flags), data);
3958}
3959
Gustavo Padovan2d792812012-10-06 10:07:01 +01003960static inline int l2cap_config_req(struct l2cap_conn *conn,
3961 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3962 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003963{
3964 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3965 u16 dcid, flags;
3966 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003967 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003968 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003969
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003970 if (cmd_len < sizeof(*req))
3971 return -EPROTO;
3972
Linus Torvalds1da177e2005-04-16 15:20:36 -07003973 dcid = __le16_to_cpu(req->dcid);
3974 flags = __le16_to_cpu(req->flags);
3975
3976 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3977
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003978 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003979 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003980 return -ENOENT;
3981
David S. Miller033b1142011-07-21 13:38:42 -07003982 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003983 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003984
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003985 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003986 rej.scid = cpu_to_le16(chan->scid);
3987 rej.dcid = cpu_to_le16(chan->dcid);
3988
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003989 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003990 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003991 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003992 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003993
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003994 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003995 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003996 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003997 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003998 l2cap_build_conf_rsp(chan, rsp,
3999 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004000 goto unlock;
4001 }
4002
4003 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004004 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4005 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004006
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004007 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004008 /* Incomplete config. Send empty response. */
4009 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004010 l2cap_build_conf_rsp(chan, rsp,
4011 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004012 goto unlock;
4013 }
4014
4015 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004016 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004017 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004018 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004019 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004020 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004021
Mat Martineau1500109b2012-10-23 15:24:15 -07004022 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004023 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004024 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004025
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004026 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004027 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004028
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004029 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004030 goto unlock;
4031
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004032 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004033 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004034
Mat Martineau105bdf92012-04-27 16:50:48 -07004035 if (chan->mode == L2CAP_MODE_ERTM ||
4036 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004037 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004038
Mat Martineau3c588192012-04-11 10:48:42 -07004039 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004040 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004041 else
4042 l2cap_chan_ready(chan);
4043
Marcel Holtmann876d9482007-10-20 13:35:42 +02004044 goto unlock;
4045 }
4046
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004047 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004048 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004049 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004050 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004051 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004052 }
4053
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004054 /* Got Conf Rsp PENDING from remote side and asume we sent
4055 Conf Rsp PENDING in the code above */
4056 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004057 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004058
4059 /* check compatibility */
4060
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004061 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004062 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004063 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4064 else
4065 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004066 }
4067
Linus Torvalds1da177e2005-04-16 15:20:36 -07004068unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004069 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004070 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004071}
4072
Gustavo Padovan2d792812012-10-06 10:07:01 +01004073static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004074 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4075 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004076{
4077 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4078 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004079 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004080 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004081 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004082
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004083 if (cmd_len < sizeof(*rsp))
4084 return -EPROTO;
4085
Linus Torvalds1da177e2005-04-16 15:20:36 -07004086 scid = __le16_to_cpu(rsp->scid);
4087 flags = __le16_to_cpu(rsp->flags);
4088 result = __le16_to_cpu(rsp->result);
4089
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004090 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4091 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004092
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004093 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004094 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004095 return 0;
4096
4097 switch (result) {
4098 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004099 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004100 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004101 break;
4102
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004103 case L2CAP_CONF_PENDING:
4104 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4105
4106 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4107 char buf[64];
4108
4109 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004110 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004111 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004112 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004113 goto done;
4114 }
4115
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004116 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004117 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4118 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004119 } else {
4120 if (l2cap_check_efs(chan)) {
4121 amp_create_logical_link(chan);
4122 chan->ident = cmd->ident;
4123 }
4124 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004125 }
4126 goto done;
4127
Linus Torvalds1da177e2005-04-16 15:20:36 -07004128 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004129 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004130 char req[64];
4131
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004132 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004133 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004134 goto done;
4135 }
4136
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004137 /* throw out any old stored conf requests */
4138 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004139 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004140 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004141 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004142 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004143 goto done;
4144 }
4145
4146 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004147 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004148 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004149 if (result != L2CAP_CONF_SUCCESS)
4150 goto done;
4151 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004152 }
4153
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004154 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004155 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004156
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004157 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004158 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004159 goto done;
4160 }
4161
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004162 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004163 goto done;
4164
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004165 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004166
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004167 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004168 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004169
Mat Martineau105bdf92012-04-27 16:50:48 -07004170 if (chan->mode == L2CAP_MODE_ERTM ||
4171 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004172 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004173
Mat Martineau3c588192012-04-11 10:48:42 -07004174 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004175 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004176 else
4177 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004178 }
4179
4180done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004181 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004182 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004183}
4184
Gustavo Padovan2d792812012-10-06 10:07:01 +01004185static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004186 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4187 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004188{
4189 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4190 struct l2cap_disconn_rsp rsp;
4191 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004192 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004193 struct sock *sk;
4194
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004195 if (cmd_len != sizeof(*req))
4196 return -EPROTO;
4197
Linus Torvalds1da177e2005-04-16 15:20:36 -07004198 scid = __le16_to_cpu(req->scid);
4199 dcid = __le16_to_cpu(req->dcid);
4200
4201 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4202
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004203 mutex_lock(&conn->chan_lock);
4204
4205 chan = __l2cap_get_chan_by_scid(conn, dcid);
4206 if (!chan) {
4207 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004208 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004209 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004210
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004211 l2cap_chan_lock(chan);
4212
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004213 sk = chan->sk;
4214
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004215 rsp.dcid = cpu_to_le16(chan->scid);
4216 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004217 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4218
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004219 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004220 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004221 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004222
Mat Martineau61d6ef32012-04-27 16:50:50 -07004223 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004224 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004225
4226 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004227
Gustavo Padovan80b98022012-05-27 22:27:51 -03004228 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004229 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004230
4231 mutex_unlock(&conn->chan_lock);
4232
Linus Torvalds1da177e2005-04-16 15:20:36 -07004233 return 0;
4234}
4235
Gustavo Padovan2d792812012-10-06 10:07:01 +01004236static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004237 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4238 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004239{
4240 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4241 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004242 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004243
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004244 if (cmd_len != sizeof(*rsp))
4245 return -EPROTO;
4246
Linus Torvalds1da177e2005-04-16 15:20:36 -07004247 scid = __le16_to_cpu(rsp->scid);
4248 dcid = __le16_to_cpu(rsp->dcid);
4249
4250 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4251
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004252 mutex_lock(&conn->chan_lock);
4253
4254 chan = __l2cap_get_chan_by_scid(conn, scid);
4255 if (!chan) {
4256 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004257 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004258 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004259
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004260 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004261
Mat Martineau61d6ef32012-04-27 16:50:50 -07004262 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004263 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004264
4265 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004266
Gustavo Padovan80b98022012-05-27 22:27:51 -03004267 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004268 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004269
4270 mutex_unlock(&conn->chan_lock);
4271
Linus Torvalds1da177e2005-04-16 15:20:36 -07004272 return 0;
4273}
4274
Gustavo Padovan2d792812012-10-06 10:07:01 +01004275static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004276 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4277 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004278{
4279 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004280 u16 type;
4281
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004282 if (cmd_len != sizeof(*req))
4283 return -EPROTO;
4284
Linus Torvalds1da177e2005-04-16 15:20:36 -07004285 type = __le16_to_cpu(req->type);
4286
4287 BT_DBG("type 0x%4.4x", type);
4288
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004289 if (type == L2CAP_IT_FEAT_MASK) {
4290 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004291 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004292 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004293 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4294 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004295 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004296 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004297 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004298 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004299 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004300 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004301
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004302 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004303 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4304 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004305 } else if (type == L2CAP_IT_FIXED_CHAN) {
4306 u8 buf[12];
4307 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004308
4309 if (enable_hs)
4310 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4311 else
4312 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4313
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004314 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4315 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004316 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004317 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4318 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004319 } else {
4320 struct l2cap_info_rsp rsp;
4321 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004322 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004323 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4324 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004325 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004326
4327 return 0;
4328}
4329
Gustavo Padovan2d792812012-10-06 10:07:01 +01004330static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004331 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4332 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004333{
4334 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4335 u16 type, result;
4336
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004337 if (cmd_len != sizeof(*rsp))
4338 return -EPROTO;
4339
Linus Torvalds1da177e2005-04-16 15:20:36 -07004340 type = __le16_to_cpu(rsp->type);
4341 result = __le16_to_cpu(rsp->result);
4342
4343 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4344
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004345 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4346 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004347 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004348 return 0;
4349
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004350 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004351
Ville Tervoadb08ed2010-08-04 09:43:33 +03004352 if (result != L2CAP_IR_SUCCESS) {
4353 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4354 conn->info_ident = 0;
4355
4356 l2cap_conn_start(conn);
4357
4358 return 0;
4359 }
4360
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004361 switch (type) {
4362 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004363 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004364
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004365 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004366 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004367 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004368
4369 conn->info_ident = l2cap_get_ident(conn);
4370
4371 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004372 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004373 } else {
4374 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4375 conn->info_ident = 0;
4376
4377 l2cap_conn_start(conn);
4378 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004379 break;
4380
4381 case L2CAP_IT_FIXED_CHAN:
4382 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004383 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004384 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004385
4386 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004387 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004388 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004389
Linus Torvalds1da177e2005-04-16 15:20:36 -07004390 return 0;
4391}
4392
Mat Martineau17009152012-10-23 15:24:07 -07004393static int l2cap_create_channel_req(struct l2cap_conn *conn,
4394 struct l2cap_cmd_hdr *cmd,
4395 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004396{
4397 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004398 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004399 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004400 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004401 u16 psm, scid;
4402
4403 if (cmd_len != sizeof(*req))
4404 return -EPROTO;
4405
4406 if (!enable_hs)
4407 return -EINVAL;
4408
4409 psm = le16_to_cpu(req->psm);
4410 scid = le16_to_cpu(req->scid);
4411
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004412 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 -07004413
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004414 /* For controller id 0 make BR/EDR connection */
4415 if (req->amp_id == HCI_BREDR_ID) {
4416 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4417 req->amp_id);
4418 return 0;
4419 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004420
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004421 /* Validate AMP controller id */
4422 hdev = hci_dev_get(req->amp_id);
4423 if (!hdev)
4424 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004425
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004426 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004427 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004428 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004429 }
4430
4431 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4432 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004433 if (chan) {
4434 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4435 struct hci_conn *hs_hcon;
4436
4437 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, conn->dst);
4438 if (!hs_hcon) {
4439 hci_dev_put(hdev);
4440 return -EFAULT;
4441 }
4442
4443 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4444
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004445 mgr->bredr_chan = chan;
4446 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004447 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004448 conn->mtu = hdev->block_mtu;
4449 }
4450
4451 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004452
4453 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004454
4455error:
4456 rsp.dcid = 0;
4457 rsp.scid = cpu_to_le16(scid);
4458 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4459 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4460
4461 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4462 sizeof(rsp), &rsp);
4463
4464 return -EFAULT;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004465}
4466
Mat Martineau8eb200b2012-10-23 15:24:17 -07004467static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4468{
4469 struct l2cap_move_chan_req req;
4470 u8 ident;
4471
4472 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4473
4474 ident = l2cap_get_ident(chan->conn);
4475 chan->ident = ident;
4476
4477 req.icid = cpu_to_le16(chan->scid);
4478 req.dest_amp_id = dest_amp_id;
4479
4480 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4481 &req);
4482
4483 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4484}
4485
Mat Martineau1500109b2012-10-23 15:24:15 -07004486static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004487{
4488 struct l2cap_move_chan_rsp rsp;
4489
Mat Martineau1500109b2012-10-23 15:24:15 -07004490 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004491
Mat Martineau1500109b2012-10-23 15:24:15 -07004492 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004493 rsp.result = cpu_to_le16(result);
4494
Mat Martineau1500109b2012-10-23 15:24:15 -07004495 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4496 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004497}
4498
Mat Martineau5b155ef2012-10-23 15:24:14 -07004499static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004500{
4501 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004502
Mat Martineau5b155ef2012-10-23 15:24:14 -07004503 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004504
Mat Martineau5b155ef2012-10-23 15:24:14 -07004505 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004506
Mat Martineau5b155ef2012-10-23 15:24:14 -07004507 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004508 cfm.result = cpu_to_le16(result);
4509
Mat Martineau5b155ef2012-10-23 15:24:14 -07004510 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4511 sizeof(cfm), &cfm);
4512
4513 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4514}
4515
4516static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4517{
4518 struct l2cap_move_chan_cfm cfm;
4519
4520 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4521
4522 cfm.icid = cpu_to_le16(icid);
4523 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4524
4525 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4526 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004527}
4528
4529static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004530 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004531{
4532 struct l2cap_move_chan_cfm_rsp rsp;
4533
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004534 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004535
4536 rsp.icid = cpu_to_le16(icid);
4537 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4538}
4539
Mat Martineau5f3847a2012-10-23 15:24:12 -07004540static void __release_logical_link(struct l2cap_chan *chan)
4541{
4542 chan->hs_hchan = NULL;
4543 chan->hs_hcon = NULL;
4544
4545 /* Placeholder - release the logical link */
4546}
4547
Mat Martineau1500109b2012-10-23 15:24:15 -07004548static void l2cap_logical_fail(struct l2cap_chan *chan)
4549{
4550 /* Logical link setup failed */
4551 if (chan->state != BT_CONNECTED) {
4552 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004553 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004554 return;
4555 }
4556
4557 switch (chan->move_role) {
4558 case L2CAP_MOVE_ROLE_RESPONDER:
4559 l2cap_move_done(chan);
4560 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4561 break;
4562 case L2CAP_MOVE_ROLE_INITIATOR:
4563 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4564 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4565 /* Remote has only sent pending or
4566 * success responses, clean up
4567 */
4568 l2cap_move_done(chan);
4569 }
4570
4571 /* Other amp move states imply that the move
4572 * has already aborted
4573 */
4574 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4575 break;
4576 }
4577}
4578
4579static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4580 struct hci_chan *hchan)
4581{
4582 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004583
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004584 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004585 chan->hs_hcon->l2cap_data = chan->conn;
4586
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004587 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004588
4589 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004590 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004591
4592 set_default_fcs(chan);
4593
4594 err = l2cap_ertm_init(chan);
4595 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004596 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004597 else
4598 l2cap_chan_ready(chan);
4599 }
4600}
4601
4602static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4603 struct hci_chan *hchan)
4604{
4605 chan->hs_hcon = hchan->conn;
4606 chan->hs_hcon->l2cap_data = chan->conn;
4607
4608 BT_DBG("move_state %d", chan->move_state);
4609
4610 switch (chan->move_state) {
4611 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4612 /* Move confirm will be sent after a success
4613 * response is received
4614 */
4615 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4616 break;
4617 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4618 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4619 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4620 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4621 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4622 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4623 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4624 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4625 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4626 }
4627 break;
4628 default:
4629 /* Move was not in expected state, free the channel */
4630 __release_logical_link(chan);
4631
4632 chan->move_state = L2CAP_MOVE_STABLE;
4633 }
4634}
4635
4636/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004637void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4638 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004639{
Mat Martineau1500109b2012-10-23 15:24:15 -07004640 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4641
4642 if (status) {
4643 l2cap_logical_fail(chan);
4644 __release_logical_link(chan);
4645 return;
4646 }
4647
4648 if (chan->state != BT_CONNECTED) {
4649 /* Ignore logical link if channel is on BR/EDR */
4650 if (chan->local_amp_id)
4651 l2cap_logical_finish_create(chan, hchan);
4652 } else {
4653 l2cap_logical_finish_move(chan, hchan);
4654 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004655}
4656
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004657void l2cap_move_start(struct l2cap_chan *chan)
4658{
4659 BT_DBG("chan %p", chan);
4660
4661 if (chan->local_amp_id == HCI_BREDR_ID) {
4662 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4663 return;
4664 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4665 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4666 /* Placeholder - start physical link setup */
4667 } else {
4668 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4669 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4670 chan->move_id = 0;
4671 l2cap_move_setup(chan);
4672 l2cap_send_move_chan_req(chan, 0);
4673 }
4674}
4675
Mat Martineau8eb200b2012-10-23 15:24:17 -07004676static void l2cap_do_create(struct l2cap_chan *chan, int result,
4677 u8 local_amp_id, u8 remote_amp_id)
4678{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004679 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4680 local_amp_id, remote_amp_id);
4681
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004682 chan->fcs = L2CAP_FCS_NONE;
4683
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004684 /* Outgoing channel on AMP */
4685 if (chan->state == BT_CONNECT) {
4686 if (result == L2CAP_CR_SUCCESS) {
4687 chan->local_amp_id = local_amp_id;
4688 l2cap_send_create_chan_req(chan, remote_amp_id);
4689 } else {
4690 /* Revert to BR/EDR connect */
4691 l2cap_send_conn_req(chan);
4692 }
4693
4694 return;
4695 }
4696
4697 /* Incoming channel on AMP */
4698 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004699 struct l2cap_conn_rsp rsp;
4700 char buf[128];
4701 rsp.scid = cpu_to_le16(chan->dcid);
4702 rsp.dcid = cpu_to_le16(chan->scid);
4703
Mat Martineau8eb200b2012-10-23 15:24:17 -07004704 if (result == L2CAP_CR_SUCCESS) {
4705 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004706 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4707 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004708 } else {
4709 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004710 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4711 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004712 }
4713
4714 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4715 sizeof(rsp), &rsp);
4716
4717 if (result == L2CAP_CR_SUCCESS) {
4718 __l2cap_state_change(chan, BT_CONFIG);
4719 set_bit(CONF_REQ_SENT, &chan->conf_state);
4720 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4721 L2CAP_CONF_REQ,
4722 l2cap_build_conf_req(chan, buf), buf);
4723 chan->num_conf_req++;
4724 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004725 }
4726}
4727
4728static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4729 u8 remote_amp_id)
4730{
4731 l2cap_move_setup(chan);
4732 chan->move_id = local_amp_id;
4733 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4734
4735 l2cap_send_move_chan_req(chan, remote_amp_id);
4736}
4737
4738static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4739{
4740 struct hci_chan *hchan = NULL;
4741
4742 /* Placeholder - get hci_chan for logical link */
4743
4744 if (hchan) {
4745 if (hchan->state == BT_CONNECTED) {
4746 /* Logical link is ready to go */
4747 chan->hs_hcon = hchan->conn;
4748 chan->hs_hcon->l2cap_data = chan->conn;
4749 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4750 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4751
4752 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4753 } else {
4754 /* Wait for logical link to be ready */
4755 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4756 }
4757 } else {
4758 /* Logical link not available */
4759 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4760 }
4761}
4762
4763static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4764{
4765 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4766 u8 rsp_result;
4767 if (result == -EINVAL)
4768 rsp_result = L2CAP_MR_BAD_ID;
4769 else
4770 rsp_result = L2CAP_MR_NOT_ALLOWED;
4771
4772 l2cap_send_move_chan_rsp(chan, rsp_result);
4773 }
4774
4775 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4776 chan->move_state = L2CAP_MOVE_STABLE;
4777
4778 /* Restart data transmission */
4779 l2cap_ertm_send(chan);
4780}
4781
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004782/* Invoke with locked chan */
4783void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004784{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004785 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004786 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004787
Mat Martineau8eb200b2012-10-23 15:24:17 -07004788 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4789 chan, result, local_amp_id, remote_amp_id);
4790
Mat Martineau8eb200b2012-10-23 15:24:17 -07004791 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4792 l2cap_chan_unlock(chan);
4793 return;
4794 }
4795
4796 if (chan->state != BT_CONNECTED) {
4797 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4798 } else if (result != L2CAP_MR_SUCCESS) {
4799 l2cap_do_move_cancel(chan, result);
4800 } else {
4801 switch (chan->move_role) {
4802 case L2CAP_MOVE_ROLE_INITIATOR:
4803 l2cap_do_move_initiate(chan, local_amp_id,
4804 remote_amp_id);
4805 break;
4806 case L2CAP_MOVE_ROLE_RESPONDER:
4807 l2cap_do_move_respond(chan, result);
4808 break;
4809 default:
4810 l2cap_do_move_cancel(chan, result);
4811 break;
4812 }
4813 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004814}
4815
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004816static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004817 struct l2cap_cmd_hdr *cmd,
4818 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004819{
4820 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004821 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004822 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004823 u16 icid = 0;
4824 u16 result = L2CAP_MR_NOT_ALLOWED;
4825
4826 if (cmd_len != sizeof(*req))
4827 return -EPROTO;
4828
4829 icid = le16_to_cpu(req->icid);
4830
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004831 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004832
4833 if (!enable_hs)
4834 return -EINVAL;
4835
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004836 chan = l2cap_get_chan_by_dcid(conn, icid);
4837 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004838 rsp.icid = cpu_to_le16(icid);
4839 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4840 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4841 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004842 return 0;
4843 }
4844
Mat Martineau1500109b2012-10-23 15:24:15 -07004845 chan->ident = cmd->ident;
4846
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004847 if (chan->scid < L2CAP_CID_DYN_START ||
4848 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4849 (chan->mode != L2CAP_MODE_ERTM &&
4850 chan->mode != L2CAP_MODE_STREAMING)) {
4851 result = L2CAP_MR_NOT_ALLOWED;
4852 goto send_move_response;
4853 }
4854
4855 if (chan->local_amp_id == req->dest_amp_id) {
4856 result = L2CAP_MR_SAME_ID;
4857 goto send_move_response;
4858 }
4859
4860 if (req->dest_amp_id) {
4861 struct hci_dev *hdev;
4862 hdev = hci_dev_get(req->dest_amp_id);
4863 if (!hdev || hdev->dev_type != HCI_AMP ||
4864 !test_bit(HCI_UP, &hdev->flags)) {
4865 if (hdev)
4866 hci_dev_put(hdev);
4867
4868 result = L2CAP_MR_BAD_ID;
4869 goto send_move_response;
4870 }
4871 hci_dev_put(hdev);
4872 }
4873
4874 /* Detect a move collision. Only send a collision response
4875 * if this side has "lost", otherwise proceed with the move.
4876 * The winner has the larger bd_addr.
4877 */
4878 if ((__chan_is_moving(chan) ||
4879 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
4880 bacmp(conn->src, conn->dst) > 0) {
4881 result = L2CAP_MR_COLLISION;
4882 goto send_move_response;
4883 }
4884
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004885 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4886 l2cap_move_setup(chan);
4887 chan->move_id = req->dest_amp_id;
4888 icid = chan->dcid;
4889
4890 if (!req->dest_amp_id) {
4891 /* Moving to BR/EDR */
4892 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4893 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4894 result = L2CAP_MR_PEND;
4895 } else {
4896 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4897 result = L2CAP_MR_SUCCESS;
4898 }
4899 } else {
4900 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4901 /* Placeholder - uncomment when amp functions are available */
4902 /*amp_accept_physical(chan, req->dest_amp_id);*/
4903 result = L2CAP_MR_PEND;
4904 }
4905
4906send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004907 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004908
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004909 l2cap_chan_unlock(chan);
4910
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004911 return 0;
4912}
4913
Mat Martineau5b155ef2012-10-23 15:24:14 -07004914static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4915{
4916 struct l2cap_chan *chan;
4917 struct hci_chan *hchan = NULL;
4918
4919 chan = l2cap_get_chan_by_scid(conn, icid);
4920 if (!chan) {
4921 l2cap_send_move_chan_cfm_icid(conn, icid);
4922 return;
4923 }
4924
4925 __clear_chan_timer(chan);
4926 if (result == L2CAP_MR_PEND)
4927 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4928
4929 switch (chan->move_state) {
4930 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4931 /* Move confirm will be sent when logical link
4932 * is complete.
4933 */
4934 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4935 break;
4936 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4937 if (result == L2CAP_MR_PEND) {
4938 break;
4939 } else if (test_bit(CONN_LOCAL_BUSY,
4940 &chan->conn_state)) {
4941 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4942 } else {
4943 /* Logical link is up or moving to BR/EDR,
4944 * proceed with move
4945 */
4946 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4947 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4948 }
4949 break;
4950 case L2CAP_MOVE_WAIT_RSP:
4951 /* Moving to AMP */
4952 if (result == L2CAP_MR_SUCCESS) {
4953 /* Remote is ready, send confirm immediately
4954 * after logical link is ready
4955 */
4956 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4957 } else {
4958 /* Both logical link and move success
4959 * are required to confirm
4960 */
4961 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
4962 }
4963
4964 /* Placeholder - get hci_chan for logical link */
4965 if (!hchan) {
4966 /* Logical link not available */
4967 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4968 break;
4969 }
4970
4971 /* If the logical link is not yet connected, do not
4972 * send confirmation.
4973 */
4974 if (hchan->state != BT_CONNECTED)
4975 break;
4976
4977 /* Logical link is already ready to go */
4978
4979 chan->hs_hcon = hchan->conn;
4980 chan->hs_hcon->l2cap_data = chan->conn;
4981
4982 if (result == L2CAP_MR_SUCCESS) {
4983 /* Can confirm now */
4984 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4985 } else {
4986 /* Now only need move success
4987 * to confirm
4988 */
4989 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4990 }
4991
4992 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4993 break;
4994 default:
4995 /* Any other amp move state means the move failed. */
4996 chan->move_id = chan->local_amp_id;
4997 l2cap_move_done(chan);
4998 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4999 }
5000
5001 l2cap_chan_unlock(chan);
5002}
5003
5004static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5005 u16 result)
5006{
5007 struct l2cap_chan *chan;
5008
5009 chan = l2cap_get_chan_by_ident(conn, ident);
5010 if (!chan) {
5011 /* Could not locate channel, icid is best guess */
5012 l2cap_send_move_chan_cfm_icid(conn, icid);
5013 return;
5014 }
5015
5016 __clear_chan_timer(chan);
5017
5018 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5019 if (result == L2CAP_MR_COLLISION) {
5020 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5021 } else {
5022 /* Cleanup - cancel move */
5023 chan->move_id = chan->local_amp_id;
5024 l2cap_move_done(chan);
5025 }
5026 }
5027
5028 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5029
5030 l2cap_chan_unlock(chan);
5031}
5032
5033static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5034 struct l2cap_cmd_hdr *cmd,
5035 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005036{
5037 struct l2cap_move_chan_rsp *rsp = data;
5038 u16 icid, result;
5039
5040 if (cmd_len != sizeof(*rsp))
5041 return -EPROTO;
5042
5043 icid = le16_to_cpu(rsp->icid);
5044 result = le16_to_cpu(rsp->result);
5045
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005046 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005047
Mat Martineau5b155ef2012-10-23 15:24:14 -07005048 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5049 l2cap_move_continue(conn, icid, result);
5050 else
5051 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005052
5053 return 0;
5054}
5055
Mat Martineau5f3847a2012-10-23 15:24:12 -07005056static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5057 struct l2cap_cmd_hdr *cmd,
5058 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005059{
5060 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005061 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005062 u16 icid, result;
5063
5064 if (cmd_len != sizeof(*cfm))
5065 return -EPROTO;
5066
5067 icid = le16_to_cpu(cfm->icid);
5068 result = le16_to_cpu(cfm->result);
5069
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005070 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005071
Mat Martineau5f3847a2012-10-23 15:24:12 -07005072 chan = l2cap_get_chan_by_dcid(conn, icid);
5073 if (!chan) {
5074 /* Spec requires a response even if the icid was not found */
5075 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5076 return 0;
5077 }
5078
5079 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5080 if (result == L2CAP_MC_CONFIRMED) {
5081 chan->local_amp_id = chan->move_id;
5082 if (!chan->local_amp_id)
5083 __release_logical_link(chan);
5084 } else {
5085 chan->move_id = chan->local_amp_id;
5086 }
5087
5088 l2cap_move_done(chan);
5089 }
5090
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005091 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5092
Mat Martineau5f3847a2012-10-23 15:24:12 -07005093 l2cap_chan_unlock(chan);
5094
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005095 return 0;
5096}
5097
5098static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005099 struct l2cap_cmd_hdr *cmd,
5100 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005101{
5102 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005103 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005104 u16 icid;
5105
5106 if (cmd_len != sizeof(*rsp))
5107 return -EPROTO;
5108
5109 icid = le16_to_cpu(rsp->icid);
5110
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005111 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005112
Mat Martineau3fd71a02012-10-23 15:24:16 -07005113 chan = l2cap_get_chan_by_scid(conn, icid);
5114 if (!chan)
5115 return 0;
5116
5117 __clear_chan_timer(chan);
5118
5119 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5120 chan->local_amp_id = chan->move_id;
5121
5122 if (!chan->local_amp_id && chan->hs_hchan)
5123 __release_logical_link(chan);
5124
5125 l2cap_move_done(chan);
5126 }
5127
5128 l2cap_chan_unlock(chan);
5129
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005130 return 0;
5131}
5132
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005133static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005134 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005135{
5136 u16 max_latency;
5137
5138 if (min > max || min < 6 || max > 3200)
5139 return -EINVAL;
5140
5141 if (to_multiplier < 10 || to_multiplier > 3200)
5142 return -EINVAL;
5143
5144 if (max >= to_multiplier * 8)
5145 return -EINVAL;
5146
5147 max_latency = (to_multiplier * 8 / max) - 1;
5148 if (latency > 499 || latency > max_latency)
5149 return -EINVAL;
5150
5151 return 0;
5152}
5153
5154static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005155 struct l2cap_cmd_hdr *cmd,
5156 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005157{
5158 struct hci_conn *hcon = conn->hcon;
5159 struct l2cap_conn_param_update_req *req;
5160 struct l2cap_conn_param_update_rsp rsp;
5161 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005162 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005163
5164 if (!(hcon->link_mode & HCI_LM_MASTER))
5165 return -EINVAL;
5166
5167 cmd_len = __le16_to_cpu(cmd->len);
5168 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5169 return -EPROTO;
5170
5171 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005172 min = __le16_to_cpu(req->min);
5173 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005174 latency = __le16_to_cpu(req->latency);
5175 to_multiplier = __le16_to_cpu(req->to_multiplier);
5176
5177 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 +01005178 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005179
5180 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005181
5182 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5183 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005184 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005185 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005186 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005187
5188 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005189 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005190
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005191 if (!err)
5192 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5193
Claudio Takahaside731152011-02-11 19:28:55 -02005194 return 0;
5195}
5196
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005197static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005198 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5199 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005200{
5201 int err = 0;
5202
5203 switch (cmd->code) {
5204 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005205 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005206 break;
5207
5208 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005209 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005210 break;
5211
5212 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005213 case L2CAP_CREATE_CHAN_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005214 err = l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005215 break;
5216
5217 case L2CAP_CONF_REQ:
5218 err = l2cap_config_req(conn, cmd, cmd_len, data);
5219 break;
5220
5221 case L2CAP_CONF_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005222 err = l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005223 break;
5224
5225 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005226 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005227 break;
5228
5229 case L2CAP_DISCONN_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005230 err = l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005231 break;
5232
5233 case L2CAP_ECHO_REQ:
5234 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5235 break;
5236
5237 case L2CAP_ECHO_RSP:
5238 break;
5239
5240 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005241 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005242 break;
5243
5244 case L2CAP_INFO_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005245 err = l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005246 break;
5247
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005248 case L2CAP_CREATE_CHAN_REQ:
5249 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5250 break;
5251
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005252 case L2CAP_MOVE_CHAN_REQ:
5253 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5254 break;
5255
5256 case L2CAP_MOVE_CHAN_RSP:
5257 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
5258 break;
5259
5260 case L2CAP_MOVE_CHAN_CFM:
5261 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5262 break;
5263
5264 case L2CAP_MOVE_CHAN_CFM_RSP:
5265 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
5266 break;
5267
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005268 default:
5269 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5270 err = -EINVAL;
5271 break;
5272 }
5273
5274 return err;
5275}
5276
5277static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005278 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005279{
5280 switch (cmd->code) {
5281 case L2CAP_COMMAND_REJ:
5282 return 0;
5283
5284 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02005285 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005286
5287 case L2CAP_CONN_PARAM_UPDATE_RSP:
5288 return 0;
5289
5290 default:
5291 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5292 return -EINVAL;
5293 }
5294}
5295
Johan Hedbergc5623552013-04-29 19:35:33 +03005296static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5297 struct sk_buff *skb)
5298{
5299 u8 *data = skb->data;
5300 int len = skb->len;
5301 struct l2cap_cmd_hdr cmd;
5302 int err;
5303
5304 l2cap_raw_recv(conn, skb);
5305
5306 while (len >= L2CAP_CMD_HDR_SIZE) {
5307 u16 cmd_len;
5308 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5309 data += L2CAP_CMD_HDR_SIZE;
5310 len -= L2CAP_CMD_HDR_SIZE;
5311
5312 cmd_len = le16_to_cpu(cmd.len);
5313
5314 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5315 cmd.ident);
5316
5317 if (cmd_len > len || !cmd.ident) {
5318 BT_DBG("corrupted command");
5319 break;
5320 }
5321
5322 err = l2cap_le_sig_cmd(conn, &cmd, data);
5323 if (err) {
5324 struct l2cap_cmd_rej_unk rej;
5325
5326 BT_ERR("Wrong link type (%d)", err);
5327
5328 /* FIXME: Map err to a valid reason */
5329 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
5330 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5331 sizeof(rej), &rej);
5332 }
5333
5334 data += cmd_len;
5335 len -= cmd_len;
5336 }
5337
5338 kfree_skb(skb);
5339}
5340
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005341static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005342 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005343{
5344 u8 *data = skb->data;
5345 int len = skb->len;
5346 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005347 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005348
5349 l2cap_raw_recv(conn, skb);
5350
5351 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005352 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005353 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5354 data += L2CAP_CMD_HDR_SIZE;
5355 len -= L2CAP_CMD_HDR_SIZE;
5356
Al Viro88219a02007-07-29 00:17:25 -07005357 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005358
Gustavo Padovan2d792812012-10-06 10:07:01 +01005359 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5360 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005361
Al Viro88219a02007-07-29 00:17:25 -07005362 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005363 BT_DBG("corrupted command");
5364 break;
5365 }
5366
Johan Hedbergc5623552013-04-29 19:35:33 +03005367 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005368 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005369 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005370
5371 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005372
5373 /* FIXME: Map err to a valid reason */
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005374 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005375 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5376 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005377 }
5378
Al Viro88219a02007-07-29 00:17:25 -07005379 data += cmd_len;
5380 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005381 }
5382
5383 kfree_skb(skb);
5384}
5385
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005386static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005387{
5388 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005389 int hdr_size;
5390
5391 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5392 hdr_size = L2CAP_EXT_HDR_SIZE;
5393 else
5394 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005395
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005396 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005397 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005398 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5399 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5400
5401 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005402 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005403 }
5404 return 0;
5405}
5406
Mat Martineau6ea00482012-05-17 20:53:52 -07005407static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005408{
Mat Martineaue31f7632012-05-17 20:53:41 -07005409 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005410
Mat Martineaue31f7632012-05-17 20:53:41 -07005411 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005412
Mat Martineaue31f7632012-05-17 20:53:41 -07005413 memset(&control, 0, sizeof(control));
5414 control.sframe = 1;
5415 control.final = 1;
5416 control.reqseq = chan->buffer_seq;
5417 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005418
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005419 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005420 control.super = L2CAP_SUPER_RNR;
5421 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005422 }
5423
Mat Martineaue31f7632012-05-17 20:53:41 -07005424 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5425 chan->unacked_frames > 0)
5426 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005427
Mat Martineaue31f7632012-05-17 20:53:41 -07005428 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005429 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005430
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005431 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005432 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5433 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5434 * send it now.
5435 */
5436 control.super = L2CAP_SUPER_RR;
5437 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005438 }
5439}
5440
Gustavo Padovan2d792812012-10-06 10:07:01 +01005441static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5442 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005443{
Mat Martineau84084a32011-07-22 14:54:00 -07005444 /* skb->len reflects data in skb as well as all fragments
5445 * skb->data_len reflects only data in fragments
5446 */
5447 if (!skb_has_frag_list(skb))
5448 skb_shinfo(skb)->frag_list = new_frag;
5449
5450 new_frag->next = NULL;
5451
5452 (*last_frag)->next = new_frag;
5453 *last_frag = new_frag;
5454
5455 skb->len += new_frag->len;
5456 skb->data_len += new_frag->len;
5457 skb->truesize += new_frag->truesize;
5458}
5459
Mat Martineau4b51dae92012-05-17 20:53:37 -07005460static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5461 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005462{
5463 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005464
Mat Martineau4b51dae92012-05-17 20:53:37 -07005465 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005466 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005467 if (chan->sdu)
5468 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005469
Gustavo Padovan80b98022012-05-27 22:27:51 -03005470 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005471 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005472
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005473 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005474 if (chan->sdu)
5475 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005476
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005477 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005478 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005479
Mat Martineau84084a32011-07-22 14:54:00 -07005480 if (chan->sdu_len > chan->imtu) {
5481 err = -EMSGSIZE;
5482 break;
5483 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005484
Mat Martineau84084a32011-07-22 14:54:00 -07005485 if (skb->len >= chan->sdu_len)
5486 break;
5487
5488 chan->sdu = skb;
5489 chan->sdu_last_frag = skb;
5490
5491 skb = NULL;
5492 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005493 break;
5494
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005495 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005496 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005497 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005498
Mat Martineau84084a32011-07-22 14:54:00 -07005499 append_skb_frag(chan->sdu, skb,
5500 &chan->sdu_last_frag);
5501 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005502
Mat Martineau84084a32011-07-22 14:54:00 -07005503 if (chan->sdu->len >= chan->sdu_len)
5504 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005505
Mat Martineau84084a32011-07-22 14:54:00 -07005506 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005507 break;
5508
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005509 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005510 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005511 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005512
Mat Martineau84084a32011-07-22 14:54:00 -07005513 append_skb_frag(chan->sdu, skb,
5514 &chan->sdu_last_frag);
5515 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005516
Mat Martineau84084a32011-07-22 14:54:00 -07005517 if (chan->sdu->len != chan->sdu_len)
5518 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005519
Gustavo Padovan80b98022012-05-27 22:27:51 -03005520 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005521
Mat Martineau84084a32011-07-22 14:54:00 -07005522 if (!err) {
5523 /* Reassembly complete */
5524 chan->sdu = NULL;
5525 chan->sdu_last_frag = NULL;
5526 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005527 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005528 break;
5529 }
5530
Mat Martineau84084a32011-07-22 14:54:00 -07005531 if (err) {
5532 kfree_skb(skb);
5533 kfree_skb(chan->sdu);
5534 chan->sdu = NULL;
5535 chan->sdu_last_frag = NULL;
5536 chan->sdu_len = 0;
5537 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005538
Mat Martineau84084a32011-07-22 14:54:00 -07005539 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005540}
5541
Mat Martineau32b32732012-10-23 15:24:11 -07005542static int l2cap_resegment(struct l2cap_chan *chan)
5543{
5544 /* Placeholder */
5545 return 0;
5546}
5547
Mat Martineaue3281402011-07-07 09:39:02 -07005548void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03005549{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005550 u8 event;
5551
5552 if (chan->mode != L2CAP_MODE_ERTM)
5553 return;
5554
5555 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005556 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005557}
5558
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005559static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5560{
Mat Martineau63838722012-05-17 20:53:45 -07005561 int err = 0;
5562 /* Pass sequential frames to l2cap_reassemble_sdu()
5563 * until a gap is encountered.
5564 */
5565
5566 BT_DBG("chan %p", chan);
5567
5568 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5569 struct sk_buff *skb;
5570 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5571 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5572
5573 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5574
5575 if (!skb)
5576 break;
5577
5578 skb_unlink(skb, &chan->srej_q);
5579 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5580 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5581 if (err)
5582 break;
5583 }
5584
5585 if (skb_queue_empty(&chan->srej_q)) {
5586 chan->rx_state = L2CAP_RX_STATE_RECV;
5587 l2cap_send_ack(chan);
5588 }
5589
5590 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005591}
5592
5593static void l2cap_handle_srej(struct l2cap_chan *chan,
5594 struct l2cap_ctrl *control)
5595{
Mat Martineauf80842a2012-05-17 20:53:46 -07005596 struct sk_buff *skb;
5597
5598 BT_DBG("chan %p, control %p", chan, control);
5599
5600 if (control->reqseq == chan->next_tx_seq) {
5601 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005602 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005603 return;
5604 }
5605
5606 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5607
5608 if (skb == NULL) {
5609 BT_DBG("Seq %d not available for retransmission",
5610 control->reqseq);
5611 return;
5612 }
5613
5614 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5615 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005616 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005617 return;
5618 }
5619
5620 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5621
5622 if (control->poll) {
5623 l2cap_pass_to_tx(chan, control);
5624
5625 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5626 l2cap_retransmit(chan, control);
5627 l2cap_ertm_send(chan);
5628
5629 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5630 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5631 chan->srej_save_reqseq = control->reqseq;
5632 }
5633 } else {
5634 l2cap_pass_to_tx_fbit(chan, control);
5635
5636 if (control->final) {
5637 if (chan->srej_save_reqseq != control->reqseq ||
5638 !test_and_clear_bit(CONN_SREJ_ACT,
5639 &chan->conn_state))
5640 l2cap_retransmit(chan, control);
5641 } else {
5642 l2cap_retransmit(chan, control);
5643 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5644 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5645 chan->srej_save_reqseq = control->reqseq;
5646 }
5647 }
5648 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005649}
5650
5651static void l2cap_handle_rej(struct l2cap_chan *chan,
5652 struct l2cap_ctrl *control)
5653{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005654 struct sk_buff *skb;
5655
5656 BT_DBG("chan %p, control %p", chan, control);
5657
5658 if (control->reqseq == chan->next_tx_seq) {
5659 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005660 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005661 return;
5662 }
5663
5664 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5665
5666 if (chan->max_tx && skb &&
5667 bt_cb(skb)->control.retries >= chan->max_tx) {
5668 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005669 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005670 return;
5671 }
5672
5673 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5674
5675 l2cap_pass_to_tx(chan, control);
5676
5677 if (control->final) {
5678 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5679 l2cap_retransmit_all(chan, control);
5680 } else {
5681 l2cap_retransmit_all(chan, control);
5682 l2cap_ertm_send(chan);
5683 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5684 set_bit(CONN_REJ_ACT, &chan->conn_state);
5685 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005686}
5687
Mat Martineau4b51dae92012-05-17 20:53:37 -07005688static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5689{
5690 BT_DBG("chan %p, txseq %d", chan, txseq);
5691
5692 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5693 chan->expected_tx_seq);
5694
5695 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5696 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005697 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005698 /* See notes below regarding "double poll" and
5699 * invalid packets.
5700 */
5701 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5702 BT_DBG("Invalid/Ignore - after SREJ");
5703 return L2CAP_TXSEQ_INVALID_IGNORE;
5704 } else {
5705 BT_DBG("Invalid - in window after SREJ sent");
5706 return L2CAP_TXSEQ_INVALID;
5707 }
5708 }
5709
5710 if (chan->srej_list.head == txseq) {
5711 BT_DBG("Expected SREJ");
5712 return L2CAP_TXSEQ_EXPECTED_SREJ;
5713 }
5714
5715 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5716 BT_DBG("Duplicate SREJ - txseq already stored");
5717 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5718 }
5719
5720 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5721 BT_DBG("Unexpected SREJ - not requested");
5722 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5723 }
5724 }
5725
5726 if (chan->expected_tx_seq == txseq) {
5727 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5728 chan->tx_win) {
5729 BT_DBG("Invalid - txseq outside tx window");
5730 return L2CAP_TXSEQ_INVALID;
5731 } else {
5732 BT_DBG("Expected");
5733 return L2CAP_TXSEQ_EXPECTED;
5734 }
5735 }
5736
5737 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01005738 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005739 BT_DBG("Duplicate - expected_tx_seq later than txseq");
5740 return L2CAP_TXSEQ_DUPLICATE;
5741 }
5742
5743 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
5744 /* A source of invalid packets is a "double poll" condition,
5745 * where delays cause us to send multiple poll packets. If
5746 * the remote stack receives and processes both polls,
5747 * sequence numbers can wrap around in such a way that a
5748 * resent frame has a sequence number that looks like new data
5749 * with a sequence gap. This would trigger an erroneous SREJ
5750 * request.
5751 *
5752 * Fortunately, this is impossible with a tx window that's
5753 * less than half of the maximum sequence number, which allows
5754 * invalid frames to be safely ignored.
5755 *
5756 * With tx window sizes greater than half of the tx window
5757 * maximum, the frame is invalid and cannot be ignored. This
5758 * causes a disconnect.
5759 */
5760
5761 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5762 BT_DBG("Invalid/Ignore - txseq outside tx window");
5763 return L2CAP_TXSEQ_INVALID_IGNORE;
5764 } else {
5765 BT_DBG("Invalid - txseq outside tx window");
5766 return L2CAP_TXSEQ_INVALID;
5767 }
5768 } else {
5769 BT_DBG("Unexpected - txseq indicates missing frames");
5770 return L2CAP_TXSEQ_UNEXPECTED;
5771 }
5772}
5773
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005774static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5775 struct l2cap_ctrl *control,
5776 struct sk_buff *skb, u8 event)
5777{
5778 int err = 0;
5779 bool skb_in_use = 0;
5780
5781 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5782 event);
5783
5784 switch (event) {
5785 case L2CAP_EV_RECV_IFRAME:
5786 switch (l2cap_classify_txseq(chan, control->txseq)) {
5787 case L2CAP_TXSEQ_EXPECTED:
5788 l2cap_pass_to_tx(chan, control);
5789
5790 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5791 BT_DBG("Busy, discarding expected seq %d",
5792 control->txseq);
5793 break;
5794 }
5795
5796 chan->expected_tx_seq = __next_seq(chan,
5797 control->txseq);
5798
5799 chan->buffer_seq = chan->expected_tx_seq;
5800 skb_in_use = 1;
5801
5802 err = l2cap_reassemble_sdu(chan, skb, control);
5803 if (err)
5804 break;
5805
5806 if (control->final) {
5807 if (!test_and_clear_bit(CONN_REJ_ACT,
5808 &chan->conn_state)) {
5809 control->final = 0;
5810 l2cap_retransmit_all(chan, control);
5811 l2cap_ertm_send(chan);
5812 }
5813 }
5814
5815 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5816 l2cap_send_ack(chan);
5817 break;
5818 case L2CAP_TXSEQ_UNEXPECTED:
5819 l2cap_pass_to_tx(chan, control);
5820
5821 /* Can't issue SREJ frames in the local busy state.
5822 * Drop this frame, it will be seen as missing
5823 * when local busy is exited.
5824 */
5825 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5826 BT_DBG("Busy, discarding unexpected seq %d",
5827 control->txseq);
5828 break;
5829 }
5830
5831 /* There was a gap in the sequence, so an SREJ
5832 * must be sent for each missing frame. The
5833 * current frame is stored for later use.
5834 */
5835 skb_queue_tail(&chan->srej_q, skb);
5836 skb_in_use = 1;
5837 BT_DBG("Queued %p (queue len %d)", skb,
5838 skb_queue_len(&chan->srej_q));
5839
5840 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5841 l2cap_seq_list_clear(&chan->srej_list);
5842 l2cap_send_srej(chan, control->txseq);
5843
5844 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5845 break;
5846 case L2CAP_TXSEQ_DUPLICATE:
5847 l2cap_pass_to_tx(chan, control);
5848 break;
5849 case L2CAP_TXSEQ_INVALID_IGNORE:
5850 break;
5851 case L2CAP_TXSEQ_INVALID:
5852 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005853 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005854 break;
5855 }
5856 break;
5857 case L2CAP_EV_RECV_RR:
5858 l2cap_pass_to_tx(chan, control);
5859 if (control->final) {
5860 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5861
Mat Martineaue6a3ee62012-10-23 15:24:22 -07005862 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
5863 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005864 control->final = 0;
5865 l2cap_retransmit_all(chan, control);
5866 }
5867
5868 l2cap_ertm_send(chan);
5869 } else if (control->poll) {
5870 l2cap_send_i_or_rr_or_rnr(chan);
5871 } else {
5872 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5873 &chan->conn_state) &&
5874 chan->unacked_frames)
5875 __set_retrans_timer(chan);
5876
5877 l2cap_ertm_send(chan);
5878 }
5879 break;
5880 case L2CAP_EV_RECV_RNR:
5881 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5882 l2cap_pass_to_tx(chan, control);
5883 if (control && control->poll) {
5884 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5885 l2cap_send_rr_or_rnr(chan, 0);
5886 }
5887 __clear_retrans_timer(chan);
5888 l2cap_seq_list_clear(&chan->retrans_list);
5889 break;
5890 case L2CAP_EV_RECV_REJ:
5891 l2cap_handle_rej(chan, control);
5892 break;
5893 case L2CAP_EV_RECV_SREJ:
5894 l2cap_handle_srej(chan, control);
5895 break;
5896 default:
5897 break;
5898 }
5899
5900 if (skb && !skb_in_use) {
5901 BT_DBG("Freeing %p", skb);
5902 kfree_skb(skb);
5903 }
5904
5905 return err;
5906}
5907
5908static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5909 struct l2cap_ctrl *control,
5910 struct sk_buff *skb, u8 event)
5911{
5912 int err = 0;
5913 u16 txseq = control->txseq;
5914 bool skb_in_use = 0;
5915
5916 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5917 event);
5918
5919 switch (event) {
5920 case L2CAP_EV_RECV_IFRAME:
5921 switch (l2cap_classify_txseq(chan, txseq)) {
5922 case L2CAP_TXSEQ_EXPECTED:
5923 /* Keep frame for reassembly later */
5924 l2cap_pass_to_tx(chan, control);
5925 skb_queue_tail(&chan->srej_q, skb);
5926 skb_in_use = 1;
5927 BT_DBG("Queued %p (queue len %d)", skb,
5928 skb_queue_len(&chan->srej_q));
5929
5930 chan->expected_tx_seq = __next_seq(chan, txseq);
5931 break;
5932 case L2CAP_TXSEQ_EXPECTED_SREJ:
5933 l2cap_seq_list_pop(&chan->srej_list);
5934
5935 l2cap_pass_to_tx(chan, control);
5936 skb_queue_tail(&chan->srej_q, skb);
5937 skb_in_use = 1;
5938 BT_DBG("Queued %p (queue len %d)", skb,
5939 skb_queue_len(&chan->srej_q));
5940
5941 err = l2cap_rx_queued_iframes(chan);
5942 if (err)
5943 break;
5944
5945 break;
5946 case L2CAP_TXSEQ_UNEXPECTED:
5947 /* Got a frame that can't be reassembled yet.
5948 * Save it for later, and send SREJs to cover
5949 * the missing frames.
5950 */
5951 skb_queue_tail(&chan->srej_q, skb);
5952 skb_in_use = 1;
5953 BT_DBG("Queued %p (queue len %d)", skb,
5954 skb_queue_len(&chan->srej_q));
5955
5956 l2cap_pass_to_tx(chan, control);
5957 l2cap_send_srej(chan, control->txseq);
5958 break;
5959 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
5960 /* This frame was requested with an SREJ, but
5961 * some expected retransmitted frames are
5962 * missing. Request retransmission of missing
5963 * SREJ'd frames.
5964 */
5965 skb_queue_tail(&chan->srej_q, skb);
5966 skb_in_use = 1;
5967 BT_DBG("Queued %p (queue len %d)", skb,
5968 skb_queue_len(&chan->srej_q));
5969
5970 l2cap_pass_to_tx(chan, control);
5971 l2cap_send_srej_list(chan, control->txseq);
5972 break;
5973 case L2CAP_TXSEQ_DUPLICATE_SREJ:
5974 /* We've already queued this frame. Drop this copy. */
5975 l2cap_pass_to_tx(chan, control);
5976 break;
5977 case L2CAP_TXSEQ_DUPLICATE:
5978 /* Expecting a later sequence number, so this frame
5979 * was already received. Ignore it completely.
5980 */
5981 break;
5982 case L2CAP_TXSEQ_INVALID_IGNORE:
5983 break;
5984 case L2CAP_TXSEQ_INVALID:
5985 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005986 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005987 break;
5988 }
5989 break;
5990 case L2CAP_EV_RECV_RR:
5991 l2cap_pass_to_tx(chan, control);
5992 if (control->final) {
5993 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5994
5995 if (!test_and_clear_bit(CONN_REJ_ACT,
5996 &chan->conn_state)) {
5997 control->final = 0;
5998 l2cap_retransmit_all(chan, control);
5999 }
6000
6001 l2cap_ertm_send(chan);
6002 } else if (control->poll) {
6003 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6004 &chan->conn_state) &&
6005 chan->unacked_frames) {
6006 __set_retrans_timer(chan);
6007 }
6008
6009 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6010 l2cap_send_srej_tail(chan);
6011 } else {
6012 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6013 &chan->conn_state) &&
6014 chan->unacked_frames)
6015 __set_retrans_timer(chan);
6016
6017 l2cap_send_ack(chan);
6018 }
6019 break;
6020 case L2CAP_EV_RECV_RNR:
6021 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6022 l2cap_pass_to_tx(chan, control);
6023 if (control->poll) {
6024 l2cap_send_srej_tail(chan);
6025 } else {
6026 struct l2cap_ctrl rr_control;
6027 memset(&rr_control, 0, sizeof(rr_control));
6028 rr_control.sframe = 1;
6029 rr_control.super = L2CAP_SUPER_RR;
6030 rr_control.reqseq = chan->buffer_seq;
6031 l2cap_send_sframe(chan, &rr_control);
6032 }
6033
6034 break;
6035 case L2CAP_EV_RECV_REJ:
6036 l2cap_handle_rej(chan, control);
6037 break;
6038 case L2CAP_EV_RECV_SREJ:
6039 l2cap_handle_srej(chan, control);
6040 break;
6041 }
6042
6043 if (skb && !skb_in_use) {
6044 BT_DBG("Freeing %p", skb);
6045 kfree_skb(skb);
6046 }
6047
6048 return err;
6049}
6050
Mat Martineau32b32732012-10-23 15:24:11 -07006051static int l2cap_finish_move(struct l2cap_chan *chan)
6052{
6053 BT_DBG("chan %p", chan);
6054
6055 chan->rx_state = L2CAP_RX_STATE_RECV;
6056
6057 if (chan->hs_hcon)
6058 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6059 else
6060 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6061
6062 return l2cap_resegment(chan);
6063}
6064
6065static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6066 struct l2cap_ctrl *control,
6067 struct sk_buff *skb, u8 event)
6068{
6069 int err;
6070
6071 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6072 event);
6073
6074 if (!control->poll)
6075 return -EPROTO;
6076
6077 l2cap_process_reqseq(chan, control->reqseq);
6078
6079 if (!skb_queue_empty(&chan->tx_q))
6080 chan->tx_send_head = skb_peek(&chan->tx_q);
6081 else
6082 chan->tx_send_head = NULL;
6083
6084 /* Rewind next_tx_seq to the point expected
6085 * by the receiver.
6086 */
6087 chan->next_tx_seq = control->reqseq;
6088 chan->unacked_frames = 0;
6089
6090 err = l2cap_finish_move(chan);
6091 if (err)
6092 return err;
6093
6094 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6095 l2cap_send_i_or_rr_or_rnr(chan);
6096
6097 if (event == L2CAP_EV_RECV_IFRAME)
6098 return -EPROTO;
6099
6100 return l2cap_rx_state_recv(chan, control, NULL, event);
6101}
6102
6103static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6104 struct l2cap_ctrl *control,
6105 struct sk_buff *skb, u8 event)
6106{
6107 int err;
6108
6109 if (!control->final)
6110 return -EPROTO;
6111
6112 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6113
6114 chan->rx_state = L2CAP_RX_STATE_RECV;
6115 l2cap_process_reqseq(chan, control->reqseq);
6116
6117 if (!skb_queue_empty(&chan->tx_q))
6118 chan->tx_send_head = skb_peek(&chan->tx_q);
6119 else
6120 chan->tx_send_head = NULL;
6121
6122 /* Rewind next_tx_seq to the point expected
6123 * by the receiver.
6124 */
6125 chan->next_tx_seq = control->reqseq;
6126 chan->unacked_frames = 0;
6127
6128 if (chan->hs_hcon)
6129 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6130 else
6131 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6132
6133 err = l2cap_resegment(chan);
6134
6135 if (!err)
6136 err = l2cap_rx_state_recv(chan, control, skb, event);
6137
6138 return err;
6139}
6140
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006141static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6142{
6143 /* Make sure reqseq is for a packet that has been sent but not acked */
6144 u16 unacked;
6145
6146 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6147 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6148}
6149
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006150static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6151 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006152{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006153 int err = 0;
6154
6155 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6156 control, skb, event, chan->rx_state);
6157
6158 if (__valid_reqseq(chan, control->reqseq)) {
6159 switch (chan->rx_state) {
6160 case L2CAP_RX_STATE_RECV:
6161 err = l2cap_rx_state_recv(chan, control, skb, event);
6162 break;
6163 case L2CAP_RX_STATE_SREJ_SENT:
6164 err = l2cap_rx_state_srej_sent(chan, control, skb,
6165 event);
6166 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006167 case L2CAP_RX_STATE_WAIT_P:
6168 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6169 break;
6170 case L2CAP_RX_STATE_WAIT_F:
6171 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6172 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006173 default:
6174 /* shut it down */
6175 break;
6176 }
6177 } else {
6178 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6179 control->reqseq, chan->next_tx_seq,
6180 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006181 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006182 }
6183
6184 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006185}
6186
6187static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6188 struct sk_buff *skb)
6189{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006190 int err = 0;
6191
6192 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6193 chan->rx_state);
6194
6195 if (l2cap_classify_txseq(chan, control->txseq) ==
6196 L2CAP_TXSEQ_EXPECTED) {
6197 l2cap_pass_to_tx(chan, control);
6198
6199 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6200 __next_seq(chan, chan->buffer_seq));
6201
6202 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6203
6204 l2cap_reassemble_sdu(chan, skb, control);
6205 } else {
6206 if (chan->sdu) {
6207 kfree_skb(chan->sdu);
6208 chan->sdu = NULL;
6209 }
6210 chan->sdu_last_frag = NULL;
6211 chan->sdu_len = 0;
6212
6213 if (skb) {
6214 BT_DBG("Freeing %p", skb);
6215 kfree_skb(skb);
6216 }
6217 }
6218
6219 chan->last_acked_seq = control->txseq;
6220 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6221
6222 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006223}
6224
6225static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6226{
6227 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6228 u16 len;
6229 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006230
Mat Martineaub76bbd62012-04-11 10:48:43 -07006231 __unpack_control(chan, skb);
6232
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006233 len = skb->len;
6234
6235 /*
6236 * We can just drop the corrupted I-frame here.
6237 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006238 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006239 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006240 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006241 goto drop;
6242
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006243 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006244 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006245
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006246 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006247 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006248
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006249 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006250 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006251 goto drop;
6252 }
6253
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006254 if (!control->sframe) {
6255 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006256
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006257 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6258 control->sar, control->reqseq, control->final,
6259 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006260
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006261 /* Validate F-bit - F=0 always valid, F=1 only
6262 * valid in TX WAIT_F
6263 */
6264 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006265 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006266
6267 if (chan->mode != L2CAP_MODE_STREAMING) {
6268 event = L2CAP_EV_RECV_IFRAME;
6269 err = l2cap_rx(chan, control, skb, event);
6270 } else {
6271 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006272 }
6273
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006274 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006275 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006276 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006277 const u8 rx_func_to_event[4] = {
6278 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6279 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6280 };
6281
6282 /* Only I-frames are expected in streaming mode */
6283 if (chan->mode == L2CAP_MODE_STREAMING)
6284 goto drop;
6285
6286 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6287 control->reqseq, control->final, control->poll,
6288 control->super);
6289
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006290 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006291 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006292 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006293 goto drop;
6294 }
6295
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006296 /* Validate F and P bits */
6297 if (control->final && (control->poll ||
6298 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6299 goto drop;
6300
6301 event = rx_func_to_event[control->super];
6302 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006303 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006304 }
6305
6306 return 0;
6307
6308drop:
6309 kfree_skb(skb);
6310 return 0;
6311}
6312
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006313static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6314 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006315{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006316 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006317
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006318 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006319 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006320 if (cid == L2CAP_CID_A2MP) {
6321 chan = a2mp_channel_create(conn, skb);
6322 if (!chan) {
6323 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006324 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006325 }
6326
6327 l2cap_chan_lock(chan);
6328 } else {
6329 BT_DBG("unknown cid 0x%4.4x", cid);
6330 /* Drop packet and return */
6331 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006332 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006333 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006334 }
6335
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006336 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006337
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006338 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006339 goto drop;
6340
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006341 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006342 case L2CAP_MODE_BASIC:
6343 /* If socket recv buffers overflows we drop data here
6344 * which is *bad* because L2CAP has to be reliable.
6345 * But we don't have any other choice. L2CAP doesn't
6346 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006347
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006348 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006349 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006350
Gustavo Padovan80b98022012-05-27 22:27:51 -03006351 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006352 goto done;
6353 break;
6354
6355 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006356 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006357 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006358 goto done;
6359
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006360 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006361 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006362 break;
6363 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006364
6365drop:
6366 kfree_skb(skb);
6367
6368done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006369 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006370}
6371
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006372static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6373 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006374{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006375 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006376
Ido Yarivc2287682012-04-20 15:46:07 -03006377 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006378 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006379 goto drop;
6380
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006381 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006382
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006383 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006384 goto drop;
6385
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006386 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006387 goto drop;
6388
Gustavo Padovan80b98022012-05-27 22:27:51 -03006389 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006390 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006391
6392drop:
6393 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006394}
6395
Marcel Holtmann72f78352013-04-23 00:59:00 -07006396static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006397 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006398{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006399 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006400
Johan Hedbergaf1c0132013-04-29 19:35:42 +03006401 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann72f78352013-04-23 00:59:00 -07006402 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006403 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006404 goto drop;
6405
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006406 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006407
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006408 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006409 goto drop;
6410
Gustavo Padovan80b98022012-05-27 22:27:51 -03006411 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006412 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006413
6414drop:
6415 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006416}
6417
Linus Torvalds1da177e2005-04-16 15:20:36 -07006418static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6419{
6420 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006421 u16 cid, len;
6422 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006423
6424 skb_pull(skb, L2CAP_HDR_SIZE);
6425 cid = __le16_to_cpu(lh->cid);
6426 len = __le16_to_cpu(lh->len);
6427
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006428 if (len != skb->len) {
6429 kfree_skb(skb);
6430 return;
6431 }
6432
Linus Torvalds1da177e2005-04-16 15:20:36 -07006433 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6434
6435 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02006436 case L2CAP_CID_LE_SIGNALING:
Johan Hedbergc5623552013-04-29 19:35:33 +03006437 l2cap_le_sig_channel(conn, skb);
6438 break;
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006439 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006440 l2cap_sig_channel(conn, skb);
6441 break;
6442
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006443 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006444 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006445 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006446 l2cap_conless_channel(conn, psm, skb);
6447 break;
6448
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006449 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006450 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006451 break;
6452
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006453 case L2CAP_CID_SMP:
6454 if (smp_sig_channel(conn, skb))
6455 l2cap_conn_del(conn->hcon, EACCES);
6456 break;
6457
Linus Torvalds1da177e2005-04-16 15:20:36 -07006458 default:
6459 l2cap_data_channel(conn, cid, skb);
6460 break;
6461 }
6462}
6463
6464/* ---- L2CAP interface with lower layer (HCI) ---- */
6465
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006466int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006467{
6468 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006469 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006470
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006471 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006472
6473 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006474 read_lock(&chan_list_lock);
6475 list_for_each_entry(c, &chan_list, global_l) {
6476 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006477
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006478 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006479 continue;
6480
6481 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006482 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006483 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006484 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006485 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006486 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
6487 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006488 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006489 lm2 |= HCI_LM_MASTER;
6490 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006491 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006492 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006493
6494 return exact ? lm1 : lm2;
6495}
6496
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006497void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006498{
Marcel Holtmann01394182006-07-03 10:02:46 +02006499 struct l2cap_conn *conn;
6500
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006501 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006502
Linus Torvalds1da177e2005-04-16 15:20:36 -07006503 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03006504 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006505 if (conn)
6506 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006507 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006508 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006509 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006510}
6511
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006512int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006513{
6514 struct l2cap_conn *conn = hcon->l2cap_data;
6515
6516 BT_DBG("hcon %p", hcon);
6517
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006518 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006519 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006520 return conn->disc_reason;
6521}
6522
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006523void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006524{
6525 BT_DBG("hcon %p reason %d", hcon, reason);
6526
Joe Perchese1750722011-06-29 18:18:29 -07006527 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006528}
6529
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006530static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006531{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006532 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006533 return;
6534
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006535 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006536 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006537 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006538 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006539 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006540 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006541 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006542 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006543 }
6544}
6545
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006546int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006547{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006548 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006549 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006550
Marcel Holtmann01394182006-07-03 10:02:46 +02006551 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006552 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006553
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006554 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006555
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006556 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306557 if (!status && encrypt)
6558 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006559 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006560 }
6561
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006562 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006563
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006564 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006565 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006566
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006567 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6568 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006569
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006570 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6571 l2cap_chan_unlock(chan);
6572 continue;
6573 }
6574
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006575 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006576 if (!status && encrypt) {
6577 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006578 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006579 }
6580
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006581 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006582 continue;
6583 }
6584
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006585 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006586 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006587 continue;
6588 }
6589
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006590 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006591 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03006592 struct sock *sk = chan->sk;
6593
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006594 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03006595 sk->sk_state_change(sk);
6596
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006597 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006598 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006599 continue;
6600 }
6601
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006602 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006603 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006604 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006605 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006606 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006607 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006608 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006609 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006610 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006611 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006612
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006613 lock_sock(sk);
6614
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006615 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006616 if (test_bit(BT_SK_DEFER_SETUP,
6617 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006618 res = L2CAP_CR_PEND;
6619 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006620 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006621 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006622 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006623 res = L2CAP_CR_SUCCESS;
6624 stat = L2CAP_CS_NO_INFO;
6625 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006626 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006627 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006628 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006629 res = L2CAP_CR_SEC_BLOCK;
6630 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006631 }
6632
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006633 release_sock(sk);
6634
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006635 rsp.scid = cpu_to_le16(chan->dcid);
6636 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006637 rsp.result = cpu_to_le16(res);
6638 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006639 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006640 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006641
6642 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6643 res == L2CAP_CR_SUCCESS) {
6644 char buf[128];
6645 set_bit(CONF_REQ_SENT, &chan->conf_state);
6646 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6647 L2CAP_CONF_REQ,
6648 l2cap_build_conf_req(chan, buf),
6649 buf);
6650 chan->num_conf_req++;
6651 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006652 }
6653
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006654 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006655 }
6656
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006657 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006658
Linus Torvalds1da177e2005-04-16 15:20:36 -07006659 return 0;
6660}
6661
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006662int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006663{
6664 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006665 struct l2cap_hdr *hdr;
6666 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006667
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006668 /* For AMP controller do not create l2cap conn */
6669 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6670 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006671
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006672 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03006673 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006674
6675 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006676 goto drop;
6677
6678 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6679
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006680 switch (flags) {
6681 case ACL_START:
6682 case ACL_START_NO_FLUSH:
6683 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006684 if (conn->rx_len) {
6685 BT_ERR("Unexpected start frame (len %d)", skb->len);
6686 kfree_skb(conn->rx_skb);
6687 conn->rx_skb = NULL;
6688 conn->rx_len = 0;
6689 l2cap_conn_unreliable(conn, ECOMM);
6690 }
6691
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006692 /* Start fragment always begin with Basic L2CAP header */
6693 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006694 BT_ERR("Frame is too short (len %d)", skb->len);
6695 l2cap_conn_unreliable(conn, ECOMM);
6696 goto drop;
6697 }
6698
6699 hdr = (struct l2cap_hdr *) skb->data;
6700 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6701
6702 if (len == skb->len) {
6703 /* Complete frame received */
6704 l2cap_recv_frame(conn, skb);
6705 return 0;
6706 }
6707
6708 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6709
6710 if (skb->len > len) {
6711 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006712 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006713 l2cap_conn_unreliable(conn, ECOMM);
6714 goto drop;
6715 }
6716
6717 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006718 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006719 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006720 goto drop;
6721
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006722 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006723 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006724 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006725 break;
6726
6727 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006728 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6729
6730 if (!conn->rx_len) {
6731 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6732 l2cap_conn_unreliable(conn, ECOMM);
6733 goto drop;
6734 }
6735
6736 if (skb->len > conn->rx_len) {
6737 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006738 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006739 kfree_skb(conn->rx_skb);
6740 conn->rx_skb = NULL;
6741 conn->rx_len = 0;
6742 l2cap_conn_unreliable(conn, ECOMM);
6743 goto drop;
6744 }
6745
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006746 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006747 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006748 conn->rx_len -= skb->len;
6749
6750 if (!conn->rx_len) {
6751 /* Complete frame received */
6752 l2cap_recv_frame(conn, conn->rx_skb);
6753 conn->rx_skb = NULL;
6754 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006755 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006756 }
6757
6758drop:
6759 kfree_skb(skb);
6760 return 0;
6761}
6762
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006763static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006764{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006765 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006766
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006767 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006768
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006769 list_for_each_entry(c, &chan_list, global_l) {
6770 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006771
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006772 seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
6773 &bt_sk(sk)->src, &bt_sk(sk)->dst,
6774 c->state, __le16_to_cpu(c->psm),
6775 c->scid, c->dcid, c->imtu, c->omtu,
6776 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006777 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006778
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006779 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006780
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006781 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006782}
6783
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006784static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6785{
6786 return single_open(file, l2cap_debugfs_show, inode->i_private);
6787}
6788
6789static const struct file_operations l2cap_debugfs_fops = {
6790 .open = l2cap_debugfs_open,
6791 .read = seq_read,
6792 .llseek = seq_lseek,
6793 .release = single_release,
6794};
6795
6796static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006797
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006798int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006799{
6800 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006801
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006802 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006803 if (err < 0)
6804 return err;
6805
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006806 if (bt_debugfs) {
Gustavo Padovan2d792812012-10-06 10:07:01 +01006807 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6808 NULL, &l2cap_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006809 if (!l2cap_debugfs)
6810 BT_ERR("Failed to create L2CAP debug file");
6811 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006812
Linus Torvalds1da177e2005-04-16 15:20:36 -07006813 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006814}
6815
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006816void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006817{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006818 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006819 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006820}
6821
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006822module_param(disable_ertm, bool, 0644);
6823MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");