blob: c87f8f94083d0b0311b352c1658bbcbb6fbab09e [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 Hedberg073d1cf2013-04-29 19:35:35 +0300507 chan->scid = L2CAP_CID_ATT;
508 chan->dcid = L2CAP_CID_ATT;
Ville Tervob62f3282011-02-10 22:38:50 -0300509 } else {
510 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300511 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300512 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300513 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200514 break;
515
516 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200517 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300518 chan->scid = L2CAP_CID_CONN_LESS;
519 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300520 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200521 break;
522
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300523 case L2CAP_CHAN_CONN_FIX_A2MP:
524 chan->scid = L2CAP_CID_A2MP;
525 chan->dcid = L2CAP_CID_A2MP;
526 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
527 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
528 break;
529
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200530 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200531 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300532 chan->scid = L2CAP_CID_SIGNALING;
533 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300534 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200535 }
536
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300537 chan->local_id = L2CAP_BESTEFFORT_ID;
538 chan->local_stype = L2CAP_SERV_BESTEFFORT;
539 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
540 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
541 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300542 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300543
Ulisses Furquim371fd832011-12-21 20:02:36 -0200544 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300545
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200546 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200547}
548
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300549void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200550{
551 mutex_lock(&conn->chan_lock);
552 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200553 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200554}
555
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300556void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200557{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300558 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200559
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300560 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200561
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300562 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200563
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900564 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300565 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300566 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200567 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200568
Ulisses Furquim371fd832011-12-21 20:02:36 -0200569 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300570
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300571 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300572
573 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
David Herrmann76a68ba2013-04-06 20:28:37 +0200574 hci_conn_drop(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300575
576 if (mgr && mgr->bredr_chan == chan)
577 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200578 }
579
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200580 if (chan->hs_hchan) {
581 struct hci_chan *hs_hchan = chan->hs_hchan;
582
583 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
584 amp_disconnect_logical_link(hs_hchan);
585 }
586
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100587 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200588
Mat Martineau28270112012-05-17 21:14:09 -0700589 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300590 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300591
Gustavo Padovanee556f62012-05-18 20:22:38 -0300592 switch(chan->mode) {
593 case L2CAP_MODE_BASIC:
594 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300595
Gustavo Padovanee556f62012-05-18 20:22:38 -0300596 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300597 __clear_retrans_timer(chan);
598 __clear_monitor_timer(chan);
599 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300600
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300601 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300602
Mat Martineau3c588192012-04-11 10:48:42 -0700603 l2cap_seq_list_free(&chan->srej_list);
604 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300605
606 /* fall through */
607
608 case L2CAP_MODE_STREAMING:
609 skb_queue_purge(&chan->tx_q);
610 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300611 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300612
613 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200614}
615
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300616void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300617{
618 struct l2cap_conn *conn = chan->conn;
619 struct sock *sk = chan->sk;
620
Gustavo Padovan2d792812012-10-06 10:07:01 +0100621 BT_DBG("chan %p state %s sk %p", chan, state_to_string(chan->state),
622 sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300623
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300624 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300625 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100626 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300627 break;
628
629 case BT_CONNECTED:
630 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300631 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100632 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300633 __set_chan_timer(chan, sk->sk_sndtimeo);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200634 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300635 } else
636 l2cap_chan_del(chan, reason);
637 break;
638
639 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300640 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100641 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300642 struct l2cap_conn_rsp rsp;
643 __u16 result;
644
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300645 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300646 result = L2CAP_CR_SEC_BLOCK;
647 else
648 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300649 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300650
651 rsp.scid = cpu_to_le16(chan->dcid);
652 rsp.dcid = cpu_to_le16(chan->scid);
653 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300654 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300655 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100656 sizeof(rsp), &rsp);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300657 }
658
659 l2cap_chan_del(chan, reason);
660 break;
661
662 case BT_CONNECT:
663 case BT_DISCONN:
664 l2cap_chan_del(chan, reason);
665 break;
666
667 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100668 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300669 break;
670 }
671}
672
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300673static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530674{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300675 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300676 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530677 case BT_SECURITY_HIGH:
678 return HCI_AT_DEDICATED_BONDING_MITM;
679 case BT_SECURITY_MEDIUM:
680 return HCI_AT_DEDICATED_BONDING;
681 default:
682 return HCI_AT_NO_BONDING;
683 }
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +0300684 } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300685 if (chan->sec_level == BT_SECURITY_LOW)
686 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530687
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300688 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530689 return HCI_AT_NO_BONDING_MITM;
690 else
691 return HCI_AT_NO_BONDING;
692 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300693 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530694 case BT_SECURITY_HIGH:
695 return HCI_AT_GENERAL_BONDING_MITM;
696 case BT_SECURITY_MEDIUM:
697 return HCI_AT_GENERAL_BONDING;
698 default:
699 return HCI_AT_NO_BONDING;
700 }
701 }
702}
703
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200704/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200705int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200706{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300707 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100708 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200709
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300710 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100711
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300712 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200713}
714
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200715static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200716{
717 u8 id;
718
719 /* Get next available identificator.
720 * 1 - 128 are used by kernel.
721 * 129 - 199 are reserved.
722 * 200 - 254 are used by utilities like l2ping, etc.
723 */
724
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200725 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200726
727 if (++conn->tx_ident > 128)
728 conn->tx_ident = 1;
729
730 id = conn->tx_ident;
731
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200732 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200733
734 return id;
735}
736
Gustavo Padovan2d792812012-10-06 10:07:01 +0100737static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
738 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200739{
740 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200741 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200742
743 BT_DBG("code 0x%2.2x", code);
744
745 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300746 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200747
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200748 if (lmp_no_flush_capable(conn->hcon->hdev))
749 flags = ACL_START_NO_FLUSH;
750 else
751 flags = ACL_START;
752
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700753 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200754 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700755
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200756 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200757}
758
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700759static bool __chan_is_moving(struct l2cap_chan *chan)
760{
761 return chan->move_state != L2CAP_MOVE_STABLE &&
762 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
763}
764
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200765static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
766{
767 struct hci_conn *hcon = chan->conn->hcon;
768 u16 flags;
769
770 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100771 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200772
Mat Martineaud5f8a752012-10-23 15:24:18 -0700773 if (chan->hs_hcon && !__chan_is_moving(chan)) {
774 if (chan->hs_hchan)
775 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
776 else
777 kfree_skb(skb);
778
779 return;
780 }
781
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200782 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100783 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200784 flags = ACL_START_NO_FLUSH;
785 else
786 flags = ACL_START;
787
788 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
789 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790}
791
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700792static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
793{
794 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
795 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
796
797 if (enh & L2CAP_CTRL_FRAME_TYPE) {
798 /* S-Frame */
799 control->sframe = 1;
800 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
801 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
802
803 control->sar = 0;
804 control->txseq = 0;
805 } else {
806 /* I-Frame */
807 control->sframe = 0;
808 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
809 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
810
811 control->poll = 0;
812 control->super = 0;
813 }
814}
815
816static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
817{
818 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
819 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
820
821 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
822 /* S-Frame */
823 control->sframe = 1;
824 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
825 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
826
827 control->sar = 0;
828 control->txseq = 0;
829 } else {
830 /* I-Frame */
831 control->sframe = 0;
832 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
833 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
834
835 control->poll = 0;
836 control->super = 0;
837 }
838}
839
840static inline void __unpack_control(struct l2cap_chan *chan,
841 struct sk_buff *skb)
842{
843 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
844 __unpack_extended_control(get_unaligned_le32(skb->data),
845 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700846 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700847 } else {
848 __unpack_enhanced_control(get_unaligned_le16(skb->data),
849 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700850 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700851 }
852}
853
854static u32 __pack_extended_control(struct l2cap_ctrl *control)
855{
856 u32 packed;
857
858 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
859 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
860
861 if (control->sframe) {
862 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
863 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
864 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
865 } else {
866 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
867 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
868 }
869
870 return packed;
871}
872
873static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
874{
875 u16 packed;
876
877 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
878 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
879
880 if (control->sframe) {
881 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
882 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
883 packed |= L2CAP_CTRL_FRAME_TYPE;
884 } else {
885 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
886 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
887 }
888
889 return packed;
890}
891
892static inline void __pack_control(struct l2cap_chan *chan,
893 struct l2cap_ctrl *control,
894 struct sk_buff *skb)
895{
896 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
897 put_unaligned_le32(__pack_extended_control(control),
898 skb->data + L2CAP_HDR_SIZE);
899 } else {
900 put_unaligned_le16(__pack_enhanced_control(control),
901 skb->data + L2CAP_HDR_SIZE);
902 }
903}
904
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300905static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
906{
907 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
908 return L2CAP_EXT_HDR_SIZE;
909 else
910 return L2CAP_ENH_HDR_SIZE;
911}
912
Mat Martineaua67d7f62012-05-17 20:53:35 -0700913static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
914 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300915{
916 struct sk_buff *skb;
917 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300918 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300919
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300920 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300921 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300922
Mat Martineaua67d7f62012-05-17 20:53:35 -0700923 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300924
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300925 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700926 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300927
928 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300929 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300930 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300931
Mat Martineaua67d7f62012-05-17 20:53:35 -0700932 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
933 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
934 else
935 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300936
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300937 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700938 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300939 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300940 }
941
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200942 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700943 return skb;
944}
945
946static void l2cap_send_sframe(struct l2cap_chan *chan,
947 struct l2cap_ctrl *control)
948{
949 struct sk_buff *skb;
950 u32 control_field;
951
952 BT_DBG("chan %p, control %p", chan, control);
953
954 if (!control->sframe)
955 return;
956
Mat Martineaub99e13a2012-10-23 15:24:19 -0700957 if (__chan_is_moving(chan))
958 return;
959
Mat Martineaua67d7f62012-05-17 20:53:35 -0700960 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
961 !control->poll)
962 control->final = 1;
963
964 if (control->super == L2CAP_SUPER_RR)
965 clear_bit(CONN_RNR_SENT, &chan->conn_state);
966 else if (control->super == L2CAP_SUPER_RNR)
967 set_bit(CONN_RNR_SENT, &chan->conn_state);
968
969 if (control->super != L2CAP_SUPER_SREJ) {
970 chan->last_acked_seq = control->reqseq;
971 __clear_ack_timer(chan);
972 }
973
974 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
975 control->final, control->poll, control->super);
976
977 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
978 control_field = __pack_extended_control(control);
979 else
980 control_field = __pack_enhanced_control(control);
981
982 skb = l2cap_create_sframe_pdu(chan, control_field);
983 if (!IS_ERR(skb))
984 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300985}
986
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700987static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300988{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700989 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300990
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700991 BT_DBG("chan %p, poll %d", chan, poll);
992
993 memset(&control, 0, sizeof(control));
994 control.sframe = 1;
995 control.poll = poll;
996
997 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
998 control.super = L2CAP_SUPER_RNR;
999 else
1000 control.super = L2CAP_SUPER_RR;
1001
1002 control.reqseq = chan->buffer_seq;
1003 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001004}
1005
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001006static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001007{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001008 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001009}
1010
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001011static bool __amp_capable(struct l2cap_chan *chan)
1012{
1013 struct l2cap_conn *conn = chan->conn;
1014
1015 if (enable_hs &&
Andrei Emeltchenko5d054162012-11-29 17:46:05 +02001016 hci_amp_capable() &&
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001017 chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED &&
1018 conn->fixed_chan_mask & L2CAP_FC_A2MP)
1019 return true;
1020 else
1021 return false;
1022}
1023
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001024static bool l2cap_check_efs(struct l2cap_chan *chan)
1025{
1026 /* Check EFS parameters */
1027 return true;
1028}
1029
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001030void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001031{
1032 struct l2cap_conn *conn = chan->conn;
1033 struct l2cap_conn_req req;
1034
1035 req.scid = cpu_to_le16(chan->scid);
1036 req.psm = chan->psm;
1037
1038 chan->ident = l2cap_get_ident(conn);
1039
1040 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1041
1042 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1043}
1044
Mat Martineau8eb200b2012-10-23 15:24:17 -07001045static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1046{
1047 struct l2cap_create_chan_req req;
1048 req.scid = cpu_to_le16(chan->scid);
1049 req.psm = chan->psm;
1050 req.amp_id = amp_id;
1051
1052 chan->ident = l2cap_get_ident(chan->conn);
1053
1054 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1055 sizeof(req), &req);
1056}
1057
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001058static void l2cap_move_setup(struct l2cap_chan *chan)
1059{
1060 struct sk_buff *skb;
1061
1062 BT_DBG("chan %p", chan);
1063
1064 if (chan->mode != L2CAP_MODE_ERTM)
1065 return;
1066
1067 __clear_retrans_timer(chan);
1068 __clear_monitor_timer(chan);
1069 __clear_ack_timer(chan);
1070
1071 chan->retry_count = 0;
1072 skb_queue_walk(&chan->tx_q, skb) {
1073 if (bt_cb(skb)->control.retries)
1074 bt_cb(skb)->control.retries = 1;
1075 else
1076 break;
1077 }
1078
1079 chan->expected_tx_seq = chan->buffer_seq;
1080
1081 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1082 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1083 l2cap_seq_list_clear(&chan->retrans_list);
1084 l2cap_seq_list_clear(&chan->srej_list);
1085 skb_queue_purge(&chan->srej_q);
1086
1087 chan->tx_state = L2CAP_TX_STATE_XMIT;
1088 chan->rx_state = L2CAP_RX_STATE_MOVE;
1089
1090 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1091}
1092
Mat Martineau5f3847a2012-10-23 15:24:12 -07001093static void l2cap_move_done(struct l2cap_chan *chan)
1094{
1095 u8 move_role = chan->move_role;
1096 BT_DBG("chan %p", chan);
1097
1098 chan->move_state = L2CAP_MOVE_STABLE;
1099 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1100
1101 if (chan->mode != L2CAP_MODE_ERTM)
1102 return;
1103
1104 switch (move_role) {
1105 case L2CAP_MOVE_ROLE_INITIATOR:
1106 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1107 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1108 break;
1109 case L2CAP_MOVE_ROLE_RESPONDER:
1110 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1111 break;
1112 }
1113}
1114
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001115static void l2cap_chan_ready(struct l2cap_chan *chan)
1116{
Mat Martineau28270112012-05-17 21:14:09 -07001117 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001118 chan->conf_state = 0;
1119 __clear_chan_timer(chan);
1120
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001121 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001122
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001123 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001124}
1125
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001126static void l2cap_start_connection(struct l2cap_chan *chan)
1127{
1128 if (__amp_capable(chan)) {
1129 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1130 a2mp_discover_amp(chan);
1131 } else {
1132 l2cap_send_conn_req(chan);
1133 }
1134}
1135
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001136static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001137{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001138 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001139
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001140 if (conn->hcon->type == LE_LINK) {
1141 l2cap_chan_ready(chan);
1142 return;
1143 }
1144
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001145 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001146 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1147 return;
1148
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001149 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001150 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001151 l2cap_start_connection(chan);
1152 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001153 } else {
1154 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001155 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001156
1157 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1158 conn->info_ident = l2cap_get_ident(conn);
1159
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001160 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001161
Gustavo Padovan2d792812012-10-06 10:07:01 +01001162 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1163 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001164 }
1165}
1166
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001167static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1168{
1169 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001170 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001171 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1172
1173 switch (mode) {
1174 case L2CAP_MODE_ERTM:
1175 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1176 case L2CAP_MODE_STREAMING:
1177 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1178 default:
1179 return 0x00;
1180 }
1181}
1182
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001183static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001184{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001185 struct sock *sk = chan->sk;
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001186 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001187 struct l2cap_disconn_req req;
1188
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001189 if (!conn)
1190 return;
1191
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001192 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001193 __clear_retrans_timer(chan);
1194 __clear_monitor_timer(chan);
1195 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001196 }
1197
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001198 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001199 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001200 return;
1201 }
1202
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001203 req.dcid = cpu_to_le16(chan->dcid);
1204 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001205 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1206 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001207
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001208 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001209 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001210 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001211 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001212}
1213
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001215static void l2cap_conn_start(struct l2cap_conn *conn)
1216{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001217 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001218
1219 BT_DBG("conn %p", conn);
1220
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001221 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001222
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001223 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001224 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001225
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001226 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001227
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001228 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001229 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001230 continue;
1231 }
1232
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001233 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001234 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001235 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001236 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001237 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001238 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001239
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001240 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001241 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001242 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001243 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001244 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001245 continue;
1246 }
1247
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001248 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001249
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001250 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001251 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001252 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001253 rsp.scid = cpu_to_le16(chan->dcid);
1254 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001255
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001256 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001257 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001258 if (test_bit(BT_SK_DEFER_SETUP,
1259 &bt_sk(sk)->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001260 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1261 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001262 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001263
1264 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001265 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001266 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1267 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001268 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001269 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001270 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001271 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1272 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001273 }
1274
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001275 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001276 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001277
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001278 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001279 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001280 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001281 continue;
1282 }
1283
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001284 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001285 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001286 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001287 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001288 }
1289
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001290 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001291 }
1292
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001293 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001294}
1295
Ido Yarivc2287682012-04-20 15:46:07 -03001296/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001297 * Returns closest match, locked.
1298 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001299static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001300 bdaddr_t *src,
1301 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001302{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001303 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001304
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001305 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001306
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001307 list_for_each_entry(c, &chan_list, global_l) {
1308 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001309
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001310 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001311 continue;
1312
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001313 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001314 int src_match, dst_match;
1315 int src_any, dst_any;
1316
Ville Tervob62f3282011-02-10 22:38:50 -03001317 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001318 src_match = !bacmp(&bt_sk(sk)->src, src);
1319 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1320 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001321 read_unlock(&chan_list_lock);
1322 return c;
1323 }
Ville Tervob62f3282011-02-10 22:38:50 -03001324
1325 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001326 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1327 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1328 if ((src_match && dst_any) || (src_any && dst_match) ||
1329 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001330 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001331 }
1332 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001333
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001334 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001335
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001336 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001337}
1338
1339static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1340{
Gustavo F. Padovanc916fbe2011-04-04 16:00:55 -03001341 struct sock *parent, *sk;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001342 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001343
1344 BT_DBG("");
1345
1346 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001347 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Ido Yarivc2287682012-04-20 15:46:07 -03001348 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001349 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001350 return;
1351
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001352 parent = pchan->sk;
1353
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001354 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001355
Gustavo Padovan80b98022012-05-27 22:27:51 -03001356 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001357 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001358 goto clean;
1359
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001360 sk = chan->sk;
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001361
Ville Tervob62f3282011-02-10 22:38:50 -03001362 hci_conn_hold(conn->hcon);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001363 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
Ville Tervob62f3282011-02-10 22:38:50 -03001364
Ville Tervob62f3282011-02-10 22:38:50 -03001365 bacpy(&bt_sk(sk)->src, conn->src);
1366 bacpy(&bt_sk(sk)->dst, conn->dst);
1367
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001368 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001369
Gustavo Padovan6754e0d2012-05-25 09:30:56 -03001370 l2cap_chan_ready(chan);
Ville Tervob62f3282011-02-10 22:38:50 -03001371
Ville Tervob62f3282011-02-10 22:38:50 -03001372clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001373 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001374}
1375
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001376static void l2cap_conn_ready(struct l2cap_conn *conn)
1377{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001378 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001379 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001380
1381 BT_DBG("conn %p", conn);
1382
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001383 if (!hcon->out && hcon->type == LE_LINK)
Ville Tervob62f3282011-02-10 22:38:50 -03001384 l2cap_le_conn_ready(conn);
1385
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001386 if (hcon->out && hcon->type == LE_LINK)
1387 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001388
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001389 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001390
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001391 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001392
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001393 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001394
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001395 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1396 l2cap_chan_unlock(chan);
1397 continue;
1398 }
1399
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001400 if (hcon->type == LE_LINK) {
1401 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001402 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001403
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001404 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001405 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001406 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001407 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001408 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001409 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001410 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001411
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001412 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001413 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001414
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001415 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001416 }
1417
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001418 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001419}
1420
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001421/* Notify sockets that we cannot guaranty reliability anymore */
1422static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1423{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001424 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001425
1426 BT_DBG("conn %p", conn);
1427
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001428 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001429
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001430 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001431 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001432 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001433 }
1434
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001435 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001436}
1437
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001438static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001439{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001440 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001441 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001442
Marcel Holtmann984947d2009-02-06 23:35:19 +01001443 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001444 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001445
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001446 l2cap_conn_start(conn);
1447}
1448
David Herrmann2c8e1412013-04-06 20:28:45 +02001449/*
1450 * l2cap_user
1451 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1452 * callback is called during registration. The ->remove callback is called
1453 * during unregistration.
1454 * An l2cap_user object can either be explicitly unregistered or when the
1455 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1456 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1457 * External modules must own a reference to the l2cap_conn object if they intend
1458 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1459 * any time if they don't.
1460 */
1461
1462int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1463{
1464 struct hci_dev *hdev = conn->hcon->hdev;
1465 int ret;
1466
1467 /* We need to check whether l2cap_conn is registered. If it is not, we
1468 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1469 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1470 * relies on the parent hci_conn object to be locked. This itself relies
1471 * on the hci_dev object to be locked. So we must lock the hci device
1472 * here, too. */
1473
1474 hci_dev_lock(hdev);
1475
1476 if (user->list.next || user->list.prev) {
1477 ret = -EINVAL;
1478 goto out_unlock;
1479 }
1480
1481 /* conn->hchan is NULL after l2cap_conn_del() was called */
1482 if (!conn->hchan) {
1483 ret = -ENODEV;
1484 goto out_unlock;
1485 }
1486
1487 ret = user->probe(conn, user);
1488 if (ret)
1489 goto out_unlock;
1490
1491 list_add(&user->list, &conn->users);
1492 ret = 0;
1493
1494out_unlock:
1495 hci_dev_unlock(hdev);
1496 return ret;
1497}
1498EXPORT_SYMBOL(l2cap_register_user);
1499
1500void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1501{
1502 struct hci_dev *hdev = conn->hcon->hdev;
1503
1504 hci_dev_lock(hdev);
1505
1506 if (!user->list.next || !user->list.prev)
1507 goto out_unlock;
1508
1509 list_del(&user->list);
1510 user->list.next = NULL;
1511 user->list.prev = NULL;
1512 user->remove(conn, user);
1513
1514out_unlock:
1515 hci_dev_unlock(hdev);
1516}
1517EXPORT_SYMBOL(l2cap_unregister_user);
1518
1519static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1520{
1521 struct l2cap_user *user;
1522
1523 while (!list_empty(&conn->users)) {
1524 user = list_first_entry(&conn->users, struct l2cap_user, list);
1525 list_del(&user->list);
1526 user->list.next = NULL;
1527 user->list.prev = NULL;
1528 user->remove(conn, user);
1529 }
1530}
1531
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001532static void l2cap_conn_del(struct hci_conn *hcon, int err)
1533{
1534 struct l2cap_conn *conn = hcon->l2cap_data;
1535 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001536
1537 if (!conn)
1538 return;
1539
1540 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1541
1542 kfree_skb(conn->rx_skb);
1543
David Herrmann2c8e1412013-04-06 20:28:45 +02001544 l2cap_unregister_all_users(conn);
1545
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001546 mutex_lock(&conn->chan_lock);
1547
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001548 /* Kill channels */
1549 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001550 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001551 l2cap_chan_lock(chan);
1552
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001553 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001554
1555 l2cap_chan_unlock(chan);
1556
Gustavo Padovan80b98022012-05-27 22:27:51 -03001557 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001558 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001559 }
1560
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001561 mutex_unlock(&conn->chan_lock);
1562
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001563 hci_chan_del(conn->hchan);
1564
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001565 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001566 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001567
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001568 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001569 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001570 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001571 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001572
1573 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001574 conn->hchan = NULL;
1575 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001576}
1577
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001578static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001579{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001580 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001581 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001582
Johan Hedbergd06cc412012-06-06 18:44:11 +08001583 BT_DBG("conn %p", conn);
1584
1585 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1586 smp_chan_destroy(conn);
1587 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1588 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001589}
1590
Claudio Takahasibaf43252013-04-11 13:55:50 -03001591static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592{
Marcel Holtmann01394182006-07-03 10:02:46 +02001593 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001594 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595
Claudio Takahasibaf43252013-04-11 13:55:50 -03001596 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597 return conn;
1598
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001599 hchan = hci_chan_create(hcon);
1600 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001603 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001604 if (!conn) {
1605 hci_chan_del(hchan);
1606 return NULL;
1607 }
1608
David Herrmann9c903e32013-04-06 20:28:44 +02001609 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001610 hcon->l2cap_data = conn;
1611 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001612 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001613 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001615 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001616
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001617 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001618 case LE_LINK:
1619 if (hcon->hdev->le_mtu) {
1620 conn->mtu = hcon->hdev->le_mtu;
1621 break;
1622 }
1623 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001624 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001625 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001626 break;
1627 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001628
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 conn->src = &hcon->hdev->bdaddr;
1630 conn->dst = &hcon->dst;
1631
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001632 conn->feat_mask = 0;
1633
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001635 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001636
1637 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001638 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001640 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001641 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001642 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001643 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001644
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001645 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001646
Linus Torvalds1da177e2005-04-16 15:20:36 -07001647 return conn;
1648}
1649
David Herrmann9c903e32013-04-06 20:28:44 +02001650static void l2cap_conn_free(struct kref *ref)
1651{
1652 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1653
1654 hci_conn_put(conn->hcon);
1655 kfree(conn);
1656}
1657
1658void l2cap_conn_get(struct l2cap_conn *conn)
1659{
1660 kref_get(&conn->ref);
1661}
1662EXPORT_SYMBOL(l2cap_conn_get);
1663
1664void l2cap_conn_put(struct l2cap_conn *conn)
1665{
1666 kref_put(&conn->ref, l2cap_conn_free);
1667}
1668EXPORT_SYMBOL(l2cap_conn_put);
1669
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671
Ido Yarivc2287682012-04-20 15:46:07 -03001672/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673 * Returns closest match.
1674 */
Ido Yarivc2287682012-04-20 15:46:07 -03001675static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1676 bdaddr_t *src,
1677 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001679 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001681 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001682
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001683 list_for_each_entry(c, &chan_list, global_l) {
1684 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001685
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001686 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687 continue;
1688
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001689 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001690 int src_match, dst_match;
1691 int src_any, dst_any;
1692
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001694 src_match = !bacmp(&bt_sk(sk)->src, src);
1695 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1696 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001697 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001698 return c;
1699 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700
1701 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001702 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1703 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1704 if ((src_match && dst_any) || (src_any && dst_match) ||
1705 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001706 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 }
1708 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001710 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001711
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001712 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713}
1714
Andre Guedes8e9f9892012-04-24 21:02:55 -03001715int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1716 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001718 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 struct l2cap_conn *conn;
1721 struct hci_conn *hcon;
1722 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001723 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001724 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001726 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301727 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001728
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001729 hdev = hci_get_route(dst, src);
1730 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 return -EHOSTUNREACH;
1732
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001733 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001735 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001736
1737 /* PSM must be odd and lsb of upper byte must be 0 */
1738 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001739 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001740 err = -EINVAL;
1741 goto done;
1742 }
1743
1744 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1745 err = -EINVAL;
1746 goto done;
1747 }
1748
1749 switch (chan->mode) {
1750 case L2CAP_MODE_BASIC:
1751 break;
1752 case L2CAP_MODE_ERTM:
1753 case L2CAP_MODE_STREAMING:
1754 if (!disable_ertm)
1755 break;
1756 /* fall through */
1757 default:
1758 err = -ENOTSUPP;
1759 goto done;
1760 }
1761
Gustavo Padovan0797e012012-05-27 22:27:54 -03001762 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001763 case BT_CONNECT:
1764 case BT_CONNECT2:
1765 case BT_CONFIG:
1766 /* Already connecting */
1767 err = 0;
1768 goto done;
1769
1770 case BT_CONNECTED:
1771 /* Already connected */
1772 err = -EISCONN;
1773 goto done;
1774
1775 case BT_OPEN:
1776 case BT_BOUND:
1777 /* Can connect */
1778 break;
1779
1780 default:
1781 err = -EBADFD;
1782 goto done;
1783 }
1784
1785 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001786 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001787 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001788 release_sock(sk);
1789
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001790 chan->psm = psm;
1791 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001793 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001794
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001795 if (chan->dcid == L2CAP_CID_ATT)
Andre Guedes8e9f9892012-04-24 21:02:55 -03001796 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001797 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001798 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001799 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001800 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001801
Ville Tervo30e76272011-02-22 16:10:53 -03001802 if (IS_ERR(hcon)) {
1803 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001805 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806
Claudio Takahasibaf43252013-04-11 13:55:50 -03001807 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001809 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001810 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811 goto done;
1812 }
1813
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001814 if (hcon->type == LE_LINK) {
1815 err = 0;
1816
1817 if (!list_empty(&conn->chan_l)) {
1818 err = -EBUSY;
David Herrmann76a68ba2013-04-06 20:28:37 +02001819 hci_conn_drop(hcon);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001820 }
1821
1822 if (err)
1823 goto done;
1824 }
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
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001833 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001834 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835
1836 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001837 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001838 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001839 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001840 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001841 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001842 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843 }
1844
Ville Tervo30e76272011-02-22 16:10:53 -03001845 err = 0;
1846
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001848 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001849 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850 hci_dev_put(hdev);
1851 return err;
1852}
1853
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001854int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001855{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001856 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001857 DECLARE_WAITQUEUE(wait, current);
1858 int err = 0;
1859 int timeo = HZ/5;
1860
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001861 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001862 set_current_state(TASK_INTERRUPTIBLE);
1863 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001864 if (!timeo)
1865 timeo = HZ/5;
1866
1867 if (signal_pending(current)) {
1868 err = sock_intr_errno(timeo);
1869 break;
1870 }
1871
1872 release_sock(sk);
1873 timeo = schedule_timeout(timeo);
1874 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001875 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001876
1877 err = sock_error(sk);
1878 if (err)
1879 break;
1880 }
1881 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001882 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001883 return err;
1884}
1885
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001886static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001887{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001888 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001889 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001890
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001891 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001892
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001893 l2cap_chan_lock(chan);
1894
Mat Martineau80909e02012-05-17 20:53:50 -07001895 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001896 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001897 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001898 return;
1899 }
1900
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001901 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001902
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001903 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001904 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001905}
1906
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001907static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001908{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001909 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001910 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001911
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001912 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001913
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001914 l2cap_chan_lock(chan);
1915
Mat Martineau80909e02012-05-17 20:53:50 -07001916 if (!chan->conn) {
1917 l2cap_chan_unlock(chan);
1918 l2cap_chan_put(chan);
1919 return;
1920 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001921
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001922 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001923 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001924 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001925}
1926
Gustavo Padovand6603662012-05-21 13:58:22 -03001927static void l2cap_streaming_send(struct l2cap_chan *chan,
1928 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001929{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001930 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001931 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001932
Mat Martineau37339372012-05-17 20:53:33 -07001933 BT_DBG("chan %p, skbs %p", chan, skbs);
1934
Mat Martineaub99e13a2012-10-23 15:24:19 -07001935 if (__chan_is_moving(chan))
1936 return;
1937
Mat Martineau37339372012-05-17 20:53:33 -07001938 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1939
1940 while (!skb_queue_empty(&chan->tx_q)) {
1941
1942 skb = skb_dequeue(&chan->tx_q);
1943
1944 bt_cb(skb)->control.retries = 1;
1945 control = &bt_cb(skb)->control;
1946
1947 control->reqseq = 0;
1948 control->txseq = chan->next_tx_seq;
1949
1950 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001951
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001952 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001953 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1954 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001955 }
1956
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001957 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001958
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001959 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001960
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001961 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001962 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001963 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001964}
1965
Szymon Janc67c9e842011-07-28 16:24:33 +02001966static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001967{
1968 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001969 struct l2cap_ctrl *control;
1970 int sent = 0;
1971
1972 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001973
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001974 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001975 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001976
Mat Martineau94122bb2012-05-02 09:42:02 -07001977 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1978 return 0;
1979
Mat Martineaub99e13a2012-10-23 15:24:19 -07001980 if (__chan_is_moving(chan))
1981 return 0;
1982
Mat Martineau18a48e72012-05-17 20:53:34 -07001983 while (chan->tx_send_head &&
1984 chan->unacked_frames < chan->remote_tx_win &&
1985 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001986
Mat Martineau18a48e72012-05-17 20:53:34 -07001987 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001988
Mat Martineau18a48e72012-05-17 20:53:34 -07001989 bt_cb(skb)->control.retries = 1;
1990 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001991
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001992 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001993 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001994
Mat Martineau18a48e72012-05-17 20:53:34 -07001995 control->reqseq = chan->buffer_seq;
1996 chan->last_acked_seq = chan->buffer_seq;
1997 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001998
Mat Martineau18a48e72012-05-17 20:53:34 -07001999 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002000
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002001 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07002002 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2003 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002004 }
2005
Mat Martineau18a48e72012-05-17 20:53:34 -07002006 /* Clone after data has been modified. Data is assumed to be
2007 read-only (for locking purposes) on cloned sk_buffs.
2008 */
2009 tx_skb = skb_clone(skb, GFP_KERNEL);
2010
2011 if (!tx_skb)
2012 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002013
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002014 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002015
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002016 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002017 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002018 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002019 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002020
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002021 if (skb_queue_is_last(&chan->tx_q, skb))
2022 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002023 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002024 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002025
2026 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002027 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002028 }
2029
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002030 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2031 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002032
2033 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002034}
2035
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002036static void l2cap_ertm_resend(struct l2cap_chan *chan)
2037{
2038 struct l2cap_ctrl control;
2039 struct sk_buff *skb;
2040 struct sk_buff *tx_skb;
2041 u16 seq;
2042
2043 BT_DBG("chan %p", chan);
2044
2045 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2046 return;
2047
Mat Martineaub99e13a2012-10-23 15:24:19 -07002048 if (__chan_is_moving(chan))
2049 return;
2050
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002051 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2052 seq = l2cap_seq_list_pop(&chan->retrans_list);
2053
2054 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2055 if (!skb) {
2056 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002057 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002058 continue;
2059 }
2060
2061 bt_cb(skb)->control.retries++;
2062 control = bt_cb(skb)->control;
2063
2064 if (chan->max_tx != 0 &&
2065 bt_cb(skb)->control.retries > chan->max_tx) {
2066 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002067 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002068 l2cap_seq_list_clear(&chan->retrans_list);
2069 break;
2070 }
2071
2072 control.reqseq = chan->buffer_seq;
2073 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2074 control.final = 1;
2075 else
2076 control.final = 0;
2077
2078 if (skb_cloned(skb)) {
2079 /* Cloned sk_buffs are read-only, so we need a
2080 * writeable copy
2081 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002082 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002083 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002084 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002085 }
2086
2087 if (!tx_skb) {
2088 l2cap_seq_list_clear(&chan->retrans_list);
2089 break;
2090 }
2091
2092 /* Update skb contents */
2093 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2094 put_unaligned_le32(__pack_extended_control(&control),
2095 tx_skb->data + L2CAP_HDR_SIZE);
2096 } else {
2097 put_unaligned_le16(__pack_enhanced_control(&control),
2098 tx_skb->data + L2CAP_HDR_SIZE);
2099 }
2100
2101 if (chan->fcs == L2CAP_FCS_CRC16) {
2102 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2103 put_unaligned_le16(fcs, skb_put(tx_skb,
2104 L2CAP_FCS_SIZE));
2105 }
2106
2107 l2cap_do_send(chan, tx_skb);
2108
2109 BT_DBG("Resent txseq %d", control.txseq);
2110
2111 chan->last_acked_seq = chan->buffer_seq;
2112 }
2113}
2114
Mat Martineauf80842a2012-05-17 20:53:46 -07002115static void l2cap_retransmit(struct l2cap_chan *chan,
2116 struct l2cap_ctrl *control)
2117{
2118 BT_DBG("chan %p, control %p", chan, control);
2119
2120 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2121 l2cap_ertm_resend(chan);
2122}
2123
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002124static void l2cap_retransmit_all(struct l2cap_chan *chan,
2125 struct l2cap_ctrl *control)
2126{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002127 struct sk_buff *skb;
2128
2129 BT_DBG("chan %p, control %p", chan, control);
2130
2131 if (control->poll)
2132 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2133
2134 l2cap_seq_list_clear(&chan->retrans_list);
2135
2136 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2137 return;
2138
2139 if (chan->unacked_frames) {
2140 skb_queue_walk(&chan->tx_q, skb) {
2141 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002142 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002143 break;
2144 }
2145
2146 skb_queue_walk_from(&chan->tx_q, skb) {
2147 if (skb == chan->tx_send_head)
2148 break;
2149
2150 l2cap_seq_list_append(&chan->retrans_list,
2151 bt_cb(skb)->control.txseq);
2152 }
2153
2154 l2cap_ertm_resend(chan);
2155 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002156}
2157
Szymon Jancb17e73b2012-01-11 10:59:47 +01002158static void l2cap_send_ack(struct l2cap_chan *chan)
2159{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002160 struct l2cap_ctrl control;
2161 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2162 chan->last_acked_seq);
2163 int threshold;
2164
2165 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2166 chan, chan->last_acked_seq, chan->buffer_seq);
2167
2168 memset(&control, 0, sizeof(control));
2169 control.sframe = 1;
2170
2171 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2172 chan->rx_state == L2CAP_RX_STATE_RECV) {
2173 __clear_ack_timer(chan);
2174 control.super = L2CAP_SUPER_RNR;
2175 control.reqseq = chan->buffer_seq;
2176 l2cap_send_sframe(chan, &control);
2177 } else {
2178 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2179 l2cap_ertm_send(chan);
2180 /* If any i-frames were sent, they included an ack */
2181 if (chan->buffer_seq == chan->last_acked_seq)
2182 frames_to_ack = 0;
2183 }
2184
Mat Martineauc20f8e32012-07-10 05:47:07 -07002185 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002186 * Calculate without mul or div
2187 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002188 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002189 threshold += threshold << 1;
2190 threshold >>= 2;
2191
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002192 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002193 threshold);
2194
2195 if (frames_to_ack >= threshold) {
2196 __clear_ack_timer(chan);
2197 control.super = L2CAP_SUPER_RR;
2198 control.reqseq = chan->buffer_seq;
2199 l2cap_send_sframe(chan, &control);
2200 frames_to_ack = 0;
2201 }
2202
2203 if (frames_to_ack)
2204 __set_ack_timer(chan);
2205 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002206}
2207
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002208static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2209 struct msghdr *msg, int len,
2210 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002211{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002212 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002213 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002214 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002215
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002216 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002217 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002218
2219 sent += count;
2220 len -= count;
2221
2222 /* Continuation fragments (no L2CAP header) */
2223 frag = &skb_shinfo(skb)->frag_list;
2224 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002225 struct sk_buff *tmp;
2226
Linus Torvalds1da177e2005-04-16 15:20:36 -07002227 count = min_t(unsigned int, conn->mtu, len);
2228
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002229 tmp = chan->ops->alloc_skb(chan, count,
2230 msg->msg_flags & MSG_DONTWAIT);
2231 if (IS_ERR(tmp))
2232 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002233
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002234 *frag = tmp;
2235
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002236 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2237 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002238
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002239 (*frag)->priority = skb->priority;
2240
Linus Torvalds1da177e2005-04-16 15:20:36 -07002241 sent += count;
2242 len -= count;
2243
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002244 skb->len += (*frag)->len;
2245 skb->data_len += (*frag)->len;
2246
Linus Torvalds1da177e2005-04-16 15:20:36 -07002247 frag = &(*frag)->next;
2248 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249
2250 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002251}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002253static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002254 struct msghdr *msg, size_t len,
2255 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002256{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002257 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002258 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002259 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002260 struct l2cap_hdr *lh;
2261
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002262 BT_DBG("chan %p len %zu priority %u", chan, len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002263
2264 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002265
2266 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002267 msg->msg_flags & MSG_DONTWAIT);
2268 if (IS_ERR(skb))
2269 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002270
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002271 skb->priority = priority;
2272
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002273 /* Create L2CAP header */
2274 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002275 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002276 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
2277 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002278
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002279 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002280 if (unlikely(err < 0)) {
2281 kfree_skb(skb);
2282 return ERR_PTR(err);
2283 }
2284 return skb;
2285}
2286
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002287static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002288 struct msghdr *msg, size_t len,
2289 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002290{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002291 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002292 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002293 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002294 struct l2cap_hdr *lh;
2295
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002296 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002297
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002298 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002299
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002300 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002301 msg->msg_flags & MSG_DONTWAIT);
2302 if (IS_ERR(skb))
2303 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002304
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002305 skb->priority = priority;
2306
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002307 /* Create L2CAP header */
2308 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002309 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002310 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002311
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002312 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002313 if (unlikely(err < 0)) {
2314 kfree_skb(skb);
2315 return ERR_PTR(err);
2316 }
2317 return skb;
2318}
2319
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002320static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002321 struct msghdr *msg, size_t len,
2322 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002323{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002324 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002325 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002326 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002327 struct l2cap_hdr *lh;
2328
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002329 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002330
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002331 if (!conn)
2332 return ERR_PTR(-ENOTCONN);
2333
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002334 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002335
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002336 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002337 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002338
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002339 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002340 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002341
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002342 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002343
2344 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002345 msg->msg_flags & MSG_DONTWAIT);
2346 if (IS_ERR(skb))
2347 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002348
2349 /* Create L2CAP header */
2350 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002351 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002352 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002353
Mat Martineau18a48e72012-05-17 20:53:34 -07002354 /* Control header is populated later */
2355 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2356 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2357 else
2358 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002359
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002360 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002361 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002362
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002363 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002364 if (unlikely(err < 0)) {
2365 kfree_skb(skb);
2366 return ERR_PTR(err);
2367 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002368
Mat Martineau18a48e72012-05-17 20:53:34 -07002369 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002370 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002371 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002372}
2373
Mat Martineau94122bb2012-05-02 09:42:02 -07002374static int l2cap_segment_sdu(struct l2cap_chan *chan,
2375 struct sk_buff_head *seg_queue,
2376 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002377{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002378 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002379 u16 sdu_len;
2380 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002381 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002382
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002383 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002384
Mat Martineau94122bb2012-05-02 09:42:02 -07002385 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2386 * so fragmented skbs are not used. The HCI layer's handling
2387 * of fragmented skbs is not compatible with ERTM's queueing.
2388 */
2389
2390 /* PDU size is derived from the HCI MTU */
2391 pdu_len = chan->conn->mtu;
2392
Mat Martineaua5495742012-10-23 15:24:21 -07002393 /* Constrain PDU size for BR/EDR connections */
2394 if (!chan->hs_hcon)
2395 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002396
2397 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002398 if (chan->fcs)
2399 pdu_len -= L2CAP_FCS_SIZE;
2400
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002401 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002402
2403 /* Remote device may have requested smaller PDUs */
2404 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2405
2406 if (len <= pdu_len) {
2407 sar = L2CAP_SAR_UNSEGMENTED;
2408 sdu_len = 0;
2409 pdu_len = len;
2410 } else {
2411 sar = L2CAP_SAR_START;
2412 sdu_len = len;
2413 pdu_len -= L2CAP_SDULEN_SIZE;
2414 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002415
2416 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002417 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002418
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002419 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002420 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002421 return PTR_ERR(skb);
2422 }
2423
Mat Martineau94122bb2012-05-02 09:42:02 -07002424 bt_cb(skb)->control.sar = sar;
2425 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002426
Mat Martineau94122bb2012-05-02 09:42:02 -07002427 len -= pdu_len;
2428 if (sdu_len) {
2429 sdu_len = 0;
2430 pdu_len += L2CAP_SDULEN_SIZE;
2431 }
2432
2433 if (len <= pdu_len) {
2434 sar = L2CAP_SAR_END;
2435 pdu_len = len;
2436 } else {
2437 sar = L2CAP_SAR_CONTINUE;
2438 }
2439 }
2440
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002441 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002442}
2443
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002444int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002445 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002446{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002447 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002448 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002449 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002450
2451 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002452 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002453 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002454 if (IS_ERR(skb))
2455 return PTR_ERR(skb);
2456
2457 l2cap_do_send(chan, skb);
2458 return len;
2459 }
2460
2461 switch (chan->mode) {
2462 case L2CAP_MODE_BASIC:
2463 /* Check outgoing MTU */
2464 if (len > chan->omtu)
2465 return -EMSGSIZE;
2466
2467 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002468 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002469 if (IS_ERR(skb))
2470 return PTR_ERR(skb);
2471
2472 l2cap_do_send(chan, skb);
2473 err = len;
2474 break;
2475
2476 case L2CAP_MODE_ERTM:
2477 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002478 /* Check outgoing MTU */
2479 if (len > chan->omtu) {
2480 err = -EMSGSIZE;
2481 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002482 }
2483
Mat Martineau94122bb2012-05-02 09:42:02 -07002484 __skb_queue_head_init(&seg_queue);
2485
2486 /* Do segmentation before calling in to the state machine,
2487 * since it's possible to block while waiting for memory
2488 * allocation.
2489 */
2490 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2491
2492 /* The channel could have been closed while segmenting,
2493 * check that it is still connected.
2494 */
2495 if (chan->state != BT_CONNECTED) {
2496 __skb_queue_purge(&seg_queue);
2497 err = -ENOTCONN;
2498 }
2499
2500 if (err)
2501 break;
2502
Mat Martineau37339372012-05-17 20:53:33 -07002503 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002504 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002505 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002506 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002507
Gustavo Padovand6603662012-05-21 13:58:22 -03002508 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002509
Mat Martineau94122bb2012-05-02 09:42:02 -07002510 /* If the skbs were not queued for sending, they'll still be in
2511 * seg_queue and need to be purged.
2512 */
2513 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002514 break;
2515
2516 default:
2517 BT_DBG("bad state %1.1x", chan->mode);
2518 err = -EBADFD;
2519 }
2520
2521 return err;
2522}
2523
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002524static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2525{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002526 struct l2cap_ctrl control;
2527 u16 seq;
2528
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002529 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002530
2531 memset(&control, 0, sizeof(control));
2532 control.sframe = 1;
2533 control.super = L2CAP_SUPER_SREJ;
2534
2535 for (seq = chan->expected_tx_seq; seq != txseq;
2536 seq = __next_seq(chan, seq)) {
2537 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2538 control.reqseq = seq;
2539 l2cap_send_sframe(chan, &control);
2540 l2cap_seq_list_append(&chan->srej_list, seq);
2541 }
2542 }
2543
2544 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002545}
2546
2547static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2548{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002549 struct l2cap_ctrl control;
2550
2551 BT_DBG("chan %p", chan);
2552
2553 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2554 return;
2555
2556 memset(&control, 0, sizeof(control));
2557 control.sframe = 1;
2558 control.super = L2CAP_SUPER_SREJ;
2559 control.reqseq = chan->srej_list.tail;
2560 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002561}
2562
2563static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2564{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002565 struct l2cap_ctrl control;
2566 u16 initial_head;
2567 u16 seq;
2568
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002569 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002570
2571 memset(&control, 0, sizeof(control));
2572 control.sframe = 1;
2573 control.super = L2CAP_SUPER_SREJ;
2574
2575 /* Capture initial list head to allow only one pass through the list. */
2576 initial_head = chan->srej_list.head;
2577
2578 do {
2579 seq = l2cap_seq_list_pop(&chan->srej_list);
2580 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2581 break;
2582
2583 control.reqseq = seq;
2584 l2cap_send_sframe(chan, &control);
2585 l2cap_seq_list_append(&chan->srej_list, seq);
2586 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002587}
2588
Mat Martineau608bcc62012-05-17 20:53:32 -07002589static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2590{
2591 struct sk_buff *acked_skb;
2592 u16 ackseq;
2593
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002594 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002595
2596 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2597 return;
2598
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002599 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002600 chan->expected_ack_seq, chan->unacked_frames);
2601
2602 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2603 ackseq = __next_seq(chan, ackseq)) {
2604
2605 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2606 if (acked_skb) {
2607 skb_unlink(acked_skb, &chan->tx_q);
2608 kfree_skb(acked_skb);
2609 chan->unacked_frames--;
2610 }
2611 }
2612
2613 chan->expected_ack_seq = reqseq;
2614
2615 if (chan->unacked_frames == 0)
2616 __clear_retrans_timer(chan);
2617
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002618 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002619}
2620
2621static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2622{
2623 BT_DBG("chan %p", chan);
2624
2625 chan->expected_tx_seq = chan->buffer_seq;
2626 l2cap_seq_list_clear(&chan->srej_list);
2627 skb_queue_purge(&chan->srej_q);
2628 chan->rx_state = L2CAP_RX_STATE_RECV;
2629}
2630
Gustavo Padovand6603662012-05-21 13:58:22 -03002631static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2632 struct l2cap_ctrl *control,
2633 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002634{
Mat Martineau608bcc62012-05-17 20:53:32 -07002635 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2636 event);
2637
2638 switch (event) {
2639 case L2CAP_EV_DATA_REQUEST:
2640 if (chan->tx_send_head == NULL)
2641 chan->tx_send_head = skb_peek(skbs);
2642
2643 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2644 l2cap_ertm_send(chan);
2645 break;
2646 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2647 BT_DBG("Enter LOCAL_BUSY");
2648 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2649
2650 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2651 /* The SREJ_SENT state must be aborted if we are to
2652 * enter the LOCAL_BUSY state.
2653 */
2654 l2cap_abort_rx_srej_sent(chan);
2655 }
2656
2657 l2cap_send_ack(chan);
2658
2659 break;
2660 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2661 BT_DBG("Exit LOCAL_BUSY");
2662 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2663
2664 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2665 struct l2cap_ctrl local_control;
2666
2667 memset(&local_control, 0, sizeof(local_control));
2668 local_control.sframe = 1;
2669 local_control.super = L2CAP_SUPER_RR;
2670 local_control.poll = 1;
2671 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002672 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002673
2674 chan->retry_count = 1;
2675 __set_monitor_timer(chan);
2676 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2677 }
2678 break;
2679 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2680 l2cap_process_reqseq(chan, control->reqseq);
2681 break;
2682 case L2CAP_EV_EXPLICIT_POLL:
2683 l2cap_send_rr_or_rnr(chan, 1);
2684 chan->retry_count = 1;
2685 __set_monitor_timer(chan);
2686 __clear_ack_timer(chan);
2687 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2688 break;
2689 case L2CAP_EV_RETRANS_TO:
2690 l2cap_send_rr_or_rnr(chan, 1);
2691 chan->retry_count = 1;
2692 __set_monitor_timer(chan);
2693 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2694 break;
2695 case L2CAP_EV_RECV_FBIT:
2696 /* Nothing to process */
2697 break;
2698 default:
2699 break;
2700 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002701}
2702
Gustavo Padovand6603662012-05-21 13:58:22 -03002703static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2704 struct l2cap_ctrl *control,
2705 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002706{
Mat Martineau608bcc62012-05-17 20:53:32 -07002707 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2708 event);
2709
2710 switch (event) {
2711 case L2CAP_EV_DATA_REQUEST:
2712 if (chan->tx_send_head == NULL)
2713 chan->tx_send_head = skb_peek(skbs);
2714 /* Queue data, but don't send. */
2715 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2716 break;
2717 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2718 BT_DBG("Enter LOCAL_BUSY");
2719 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2720
2721 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2722 /* The SREJ_SENT state must be aborted if we are to
2723 * enter the LOCAL_BUSY state.
2724 */
2725 l2cap_abort_rx_srej_sent(chan);
2726 }
2727
2728 l2cap_send_ack(chan);
2729
2730 break;
2731 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2732 BT_DBG("Exit LOCAL_BUSY");
2733 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2734
2735 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2736 struct l2cap_ctrl local_control;
2737 memset(&local_control, 0, sizeof(local_control));
2738 local_control.sframe = 1;
2739 local_control.super = L2CAP_SUPER_RR;
2740 local_control.poll = 1;
2741 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002742 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002743
2744 chan->retry_count = 1;
2745 __set_monitor_timer(chan);
2746 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2747 }
2748 break;
2749 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2750 l2cap_process_reqseq(chan, control->reqseq);
2751
2752 /* Fall through */
2753
2754 case L2CAP_EV_RECV_FBIT:
2755 if (control && control->final) {
2756 __clear_monitor_timer(chan);
2757 if (chan->unacked_frames > 0)
2758 __set_retrans_timer(chan);
2759 chan->retry_count = 0;
2760 chan->tx_state = L2CAP_TX_STATE_XMIT;
2761 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2762 }
2763 break;
2764 case L2CAP_EV_EXPLICIT_POLL:
2765 /* Ignore */
2766 break;
2767 case L2CAP_EV_MONITOR_TO:
2768 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2769 l2cap_send_rr_or_rnr(chan, 1);
2770 __set_monitor_timer(chan);
2771 chan->retry_count++;
2772 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002773 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002774 }
2775 break;
2776 default:
2777 break;
2778 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002779}
2780
Gustavo Padovand6603662012-05-21 13:58:22 -03002781static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2782 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002783{
Mat Martineau608bcc62012-05-17 20:53:32 -07002784 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2785 chan, control, skbs, event, chan->tx_state);
2786
2787 switch (chan->tx_state) {
2788 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002789 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002790 break;
2791 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002792 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002793 break;
2794 default:
2795 /* Ignore event */
2796 break;
2797 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002798}
2799
Mat Martineau4b51dae92012-05-17 20:53:37 -07002800static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2801 struct l2cap_ctrl *control)
2802{
2803 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002804 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002805}
2806
Mat Martineauf80842a2012-05-17 20:53:46 -07002807static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2808 struct l2cap_ctrl *control)
2809{
2810 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002811 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002812}
2813
Linus Torvalds1da177e2005-04-16 15:20:36 -07002814/* Copy frame to all raw sockets on that connection */
2815static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2816{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002818 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002819
2820 BT_DBG("conn %p", conn);
2821
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002822 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002823
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002824 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002825 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002826 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002827 continue;
2828
2829 /* Don't send frame to the socket it came from */
2830 if (skb->sk == sk)
2831 continue;
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002832 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002833 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002834 continue;
2835
Gustavo Padovan80b98022012-05-27 22:27:51 -03002836 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002837 kfree_skb(nskb);
2838 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002839
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002840 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002841}
2842
2843/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002844static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2845 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002846{
2847 struct sk_buff *skb, **frag;
2848 struct l2cap_cmd_hdr *cmd;
2849 struct l2cap_hdr *lh;
2850 int len, count;
2851
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002852 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2853 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002854
Anderson Lizardo300b9622013-06-02 16:30:40 -04002855 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2856 return NULL;
2857
Linus Torvalds1da177e2005-04-16 15:20:36 -07002858 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2859 count = min_t(unsigned int, conn->mtu, len);
2860
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002861 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002862 if (!skb)
2863 return NULL;
2864
2865 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002866 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002867
2868 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002869 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002870 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002871 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002872
2873 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2874 cmd->code = code;
2875 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002876 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002877
2878 if (dlen) {
2879 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2880 memcpy(skb_put(skb, count), data, count);
2881 data += count;
2882 }
2883
2884 len -= skb->len;
2885
2886 /* Continuation fragments (no L2CAP header) */
2887 frag = &skb_shinfo(skb)->frag_list;
2888 while (len) {
2889 count = min_t(unsigned int, conn->mtu, len);
2890
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002891 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002892 if (!*frag)
2893 goto fail;
2894
2895 memcpy(skb_put(*frag, count), data, count);
2896
2897 len -= count;
2898 data += count;
2899
2900 frag = &(*frag)->next;
2901 }
2902
2903 return skb;
2904
2905fail:
2906 kfree_skb(skb);
2907 return NULL;
2908}
2909
Gustavo Padovan2d792812012-10-06 10:07:01 +01002910static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2911 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002912{
2913 struct l2cap_conf_opt *opt = *ptr;
2914 int len;
2915
2916 len = L2CAP_CONF_OPT_SIZE + opt->len;
2917 *ptr += len;
2918
2919 *type = opt->type;
2920 *olen = opt->len;
2921
2922 switch (opt->len) {
2923 case 1:
2924 *val = *((u8 *) opt->val);
2925 break;
2926
2927 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002928 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002929 break;
2930
2931 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002932 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002933 break;
2934
2935 default:
2936 *val = (unsigned long) opt->val;
2937 break;
2938 }
2939
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002940 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002941 return len;
2942}
2943
Linus Torvalds1da177e2005-04-16 15:20:36 -07002944static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2945{
2946 struct l2cap_conf_opt *opt = *ptr;
2947
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002948 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002949
2950 opt->type = type;
2951 opt->len = len;
2952
2953 switch (len) {
2954 case 1:
2955 *((u8 *) opt->val) = val;
2956 break;
2957
2958 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002959 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002960 break;
2961
2962 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002963 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002964 break;
2965
2966 default:
2967 memcpy(opt->val, (void *) val, len);
2968 break;
2969 }
2970
2971 *ptr += L2CAP_CONF_OPT_SIZE + len;
2972}
2973
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002974static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2975{
2976 struct l2cap_conf_efs efs;
2977
Szymon Janc1ec918c2011-11-16 09:32:21 +01002978 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002979 case L2CAP_MODE_ERTM:
2980 efs.id = chan->local_id;
2981 efs.stype = chan->local_stype;
2982 efs.msdu = cpu_to_le16(chan->local_msdu);
2983 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002984 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002985 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002986 break;
2987
2988 case L2CAP_MODE_STREAMING:
2989 efs.id = 1;
2990 efs.stype = L2CAP_SERV_BESTEFFORT;
2991 efs.msdu = cpu_to_le16(chan->local_msdu);
2992 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2993 efs.acc_lat = 0;
2994 efs.flush_to = 0;
2995 break;
2996
2997 default:
2998 return;
2999 }
3000
3001 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003002 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003003}
3004
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003005static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003006{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003007 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003008 ack_timer.work);
3009 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003010
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003011 BT_DBG("chan %p", chan);
3012
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003013 l2cap_chan_lock(chan);
3014
Mat Martineau03625202012-05-17 20:53:51 -07003015 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3016 chan->last_acked_seq);
3017
3018 if (frames_to_ack)
3019 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003020
3021 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003022 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003023}
3024
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003025int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003026{
Mat Martineau3c588192012-04-11 10:48:42 -07003027 int err;
3028
Mat Martineau105bdf92012-04-27 16:50:48 -07003029 chan->next_tx_seq = 0;
3030 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003031 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003032 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003033 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003034 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003035 chan->last_acked_seq = 0;
3036 chan->sdu = NULL;
3037 chan->sdu_last_frag = NULL;
3038 chan->sdu_len = 0;
3039
Mat Martineaud34c34f2012-05-14 14:49:27 -07003040 skb_queue_head_init(&chan->tx_q);
3041
Mat Martineau08333282012-10-23 15:24:06 -07003042 chan->local_amp_id = 0;
3043 chan->move_id = 0;
3044 chan->move_state = L2CAP_MOVE_STABLE;
3045 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3046
Mat Martineau105bdf92012-04-27 16:50:48 -07003047 if (chan->mode != L2CAP_MODE_ERTM)
3048 return 0;
3049
3050 chan->rx_state = L2CAP_RX_STATE_RECV;
3051 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003052
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003053 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3054 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3055 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003056
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003057 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003058
Mat Martineau3c588192012-04-11 10:48:42 -07003059 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3060 if (err < 0)
3061 return err;
3062
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003063 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3064 if (err < 0)
3065 l2cap_seq_list_free(&chan->srej_list);
3066
3067 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003068}
3069
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003070static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3071{
3072 switch (mode) {
3073 case L2CAP_MODE_STREAMING:
3074 case L2CAP_MODE_ERTM:
3075 if (l2cap_mode_supported(mode, remote_feat_mask))
3076 return mode;
3077 /* fall through */
3078 default:
3079 return L2CAP_MODE_BASIC;
3080 }
3081}
3082
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003083static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
3084{
3085 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
3086}
3087
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003088static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
3089{
3090 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
3091}
3092
Mat Martineau36c86c82012-10-23 15:24:20 -07003093static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3094 struct l2cap_conf_rfc *rfc)
3095{
3096 if (chan->local_amp_id && chan->hs_hcon) {
3097 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3098
3099 /* Class 1 devices have must have ERTM timeouts
3100 * exceeding the Link Supervision Timeout. The
3101 * default Link Supervision Timeout for AMP
3102 * controllers is 10 seconds.
3103 *
3104 * Class 1 devices use 0xffffffff for their
3105 * best-effort flush timeout, so the clamping logic
3106 * will result in a timeout that meets the above
3107 * requirement. ERTM timeouts are 16-bit values, so
3108 * the maximum timeout is 65.535 seconds.
3109 */
3110
3111 /* Convert timeout to milliseconds and round */
3112 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3113
3114 /* This is the recommended formula for class 2 devices
3115 * that start ERTM timers when packets are sent to the
3116 * controller.
3117 */
3118 ertm_to = 3 * ertm_to + 500;
3119
3120 if (ertm_to > 0xffff)
3121 ertm_to = 0xffff;
3122
3123 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3124 rfc->monitor_timeout = rfc->retrans_timeout;
3125 } else {
3126 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3127 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3128 }
3129}
3130
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003131static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3132{
3133 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003134 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003135 /* use extended control field */
3136 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003137 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3138 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003139 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003140 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003141 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3142 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003143 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003144}
3145
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003146static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003147{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003148 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003149 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003150 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003151 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003152
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003153 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003154
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003155 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003156 goto done;
3157
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003158 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003159 case L2CAP_MODE_STREAMING:
3160 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003161 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003162 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003163
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003164 if (__l2cap_efs_supported(chan))
3165 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3166
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003167 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003168 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003169 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003170 break;
3171 }
3172
3173done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003174 if (chan->imtu != L2CAP_DEFAULT_MTU)
3175 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003176
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003177 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003178 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003179 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003180 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003181 break;
3182
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003183 rfc.mode = L2CAP_MODE_BASIC;
3184 rfc.txwin_size = 0;
3185 rfc.max_transmit = 0;
3186 rfc.retrans_timeout = 0;
3187 rfc.monitor_timeout = 0;
3188 rfc.max_pdu_size = 0;
3189
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003190 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003191 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003192 break;
3193
3194 case L2CAP_MODE_ERTM:
3195 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003196 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003197
3198 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003199
3200 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003201 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3202 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003203 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003204
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003205 l2cap_txwin_setup(chan);
3206
3207 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003208 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003209
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003210 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003211 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003212
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003213 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3214 l2cap_add_opt_efs(&ptr, chan);
3215
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003216 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3217 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003218 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003219
3220 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3221 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003222 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003223 chan->fcs = L2CAP_FCS_NONE;
3224 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3225 chan->fcs);
3226 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003227 break;
3228
3229 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003230 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003231 rfc.mode = L2CAP_MODE_STREAMING;
3232 rfc.txwin_size = 0;
3233 rfc.max_transmit = 0;
3234 rfc.retrans_timeout = 0;
3235 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003236
3237 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003238 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3239 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003240 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003241
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003242 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003243 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003244
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003245 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3246 l2cap_add_opt_efs(&ptr, chan);
3247
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003248 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3249 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003250 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003251 chan->fcs = L2CAP_FCS_NONE;
3252 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3253 chan->fcs);
3254 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003255 break;
3256 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003257
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003258 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003259 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003260
3261 return ptr - data;
3262}
3263
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003264static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003265{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003266 struct l2cap_conf_rsp *rsp = data;
3267 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003268 void *req = chan->conf_req;
3269 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003270 int type, hint, olen;
3271 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003272 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003273 struct l2cap_conf_efs efs;
3274 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003275 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003276 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003277 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003278
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003279 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003280
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003281 while (len >= L2CAP_CONF_OPT_SIZE) {
3282 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003283
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003284 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003285 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003286
3287 switch (type) {
3288 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003289 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003290 break;
3291
3292 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003293 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003294 break;
3295
3296 case L2CAP_CONF_QOS:
3297 break;
3298
Marcel Holtmann6464f352007-10-20 13:39:51 +02003299 case L2CAP_CONF_RFC:
3300 if (olen == sizeof(rfc))
3301 memcpy(&rfc, (void *) val, olen);
3302 break;
3303
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003304 case L2CAP_CONF_FCS:
3305 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003306 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003307 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003308
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003309 case L2CAP_CONF_EFS:
3310 remote_efs = 1;
3311 if (olen == sizeof(efs))
3312 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003313 break;
3314
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003315 case L2CAP_CONF_EWS:
3316 if (!enable_hs)
3317 return -ECONNREFUSED;
3318
3319 set_bit(FLAG_EXT_CTRL, &chan->flags);
3320 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003321 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003322 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003323 break;
3324
3325 default:
3326 if (hint)
3327 break;
3328
3329 result = L2CAP_CONF_UNKNOWN;
3330 *((u8 *) ptr++) = type;
3331 break;
3332 }
3333 }
3334
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003335 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003336 goto done;
3337
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003338 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003339 case L2CAP_MODE_STREAMING:
3340 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003341 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003342 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003343 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003344 break;
3345 }
3346
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003347 if (remote_efs) {
3348 if (__l2cap_efs_supported(chan))
3349 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3350 else
3351 return -ECONNREFUSED;
3352 }
3353
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003354 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003355 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003356
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003357 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003358 }
3359
3360done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003361 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003362 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003363 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003364
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003365 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003366 return -ECONNREFUSED;
3367
Gustavo Padovan2d792812012-10-06 10:07:01 +01003368 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3369 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003370 }
3371
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003372 if (result == L2CAP_CONF_SUCCESS) {
3373 /* Configure output options and let the other side know
3374 * which ones we don't like. */
3375
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003376 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3377 result = L2CAP_CONF_UNACCEPT;
3378 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003379 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003380 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003381 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003382 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003383
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003384 if (remote_efs) {
3385 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003386 efs.stype != L2CAP_SERV_NOTRAFIC &&
3387 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003388
3389 result = L2CAP_CONF_UNACCEPT;
3390
3391 if (chan->num_conf_req >= 1)
3392 return -ECONNREFUSED;
3393
3394 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003395 sizeof(efs),
3396 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003397 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003398 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003399 result = L2CAP_CONF_PENDING;
3400 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003401 }
3402 }
3403
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003404 switch (rfc.mode) {
3405 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003406 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003407 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003408 break;
3409
3410 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003411 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3412 chan->remote_tx_win = rfc.txwin_size;
3413 else
3414 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3415
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003416 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003417
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003418 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003419 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3420 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003421 rfc.max_pdu_size = cpu_to_le16(size);
3422 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003423
Mat Martineau36c86c82012-10-23 15:24:20 -07003424 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003425
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003426 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003427
3428 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003429 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003430
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003431 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3432 chan->remote_id = efs.id;
3433 chan->remote_stype = efs.stype;
3434 chan->remote_msdu = le16_to_cpu(efs.msdu);
3435 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003436 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003437 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003438 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003439 chan->remote_sdu_itime =
3440 le32_to_cpu(efs.sdu_itime);
3441 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003442 sizeof(efs),
3443 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003444 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003445 break;
3446
3447 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003448 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003449 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3450 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003451 rfc.max_pdu_size = cpu_to_le16(size);
3452 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003453
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003454 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003455
Gustavo Padovan2d792812012-10-06 10:07:01 +01003456 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3457 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003458
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003459 break;
3460
3461 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003462 result = L2CAP_CONF_UNACCEPT;
3463
3464 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003465 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003466 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003467
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003468 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003469 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003470 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003471 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003472 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003473 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003474
3475 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003476}
3477
Gustavo Padovan2d792812012-10-06 10:07:01 +01003478static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3479 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003480{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003481 struct l2cap_conf_req *req = data;
3482 void *ptr = req->data;
3483 int type, olen;
3484 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003485 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003486 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003487
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003488 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003489
3490 while (len >= L2CAP_CONF_OPT_SIZE) {
3491 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3492
3493 switch (type) {
3494 case L2CAP_CONF_MTU:
3495 if (val < L2CAP_DEFAULT_MIN_MTU) {
3496 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003497 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003498 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003499 chan->imtu = val;
3500 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003501 break;
3502
3503 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003504 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003505 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003506 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003507 break;
3508
3509 case L2CAP_CONF_RFC:
3510 if (olen == sizeof(rfc))
3511 memcpy(&rfc, (void *)val, olen);
3512
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003513 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003514 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003515 return -ECONNREFUSED;
3516
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003517 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003518
3519 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003520 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003521 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003522
3523 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003524 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003525 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003526 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003527 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003528
3529 case L2CAP_CONF_EFS:
3530 if (olen == sizeof(efs))
3531 memcpy(&efs, (void *)val, olen);
3532
3533 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003534 efs.stype != L2CAP_SERV_NOTRAFIC &&
3535 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003536 return -ECONNREFUSED;
3537
Gustavo Padovan2d792812012-10-06 10:07:01 +01003538 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3539 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003540 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003541
3542 case L2CAP_CONF_FCS:
3543 if (*result == L2CAP_CONF_PENDING)
3544 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003545 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003546 &chan->conf_state);
3547 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003548 }
3549 }
3550
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003551 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003552 return -ECONNREFUSED;
3553
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003554 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003555
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003556 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003557 switch (rfc.mode) {
3558 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003559 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3560 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3561 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003562 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3563 chan->ack_win = min_t(u16, chan->ack_win,
3564 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003565
3566 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3567 chan->local_msdu = le16_to_cpu(efs.msdu);
3568 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003569 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003570 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3571 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003572 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003573 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003574 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003575
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003576 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003577 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003578 }
3579 }
3580
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003581 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003582 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003583
3584 return ptr - data;
3585}
3586
Gustavo Padovan2d792812012-10-06 10:07:01 +01003587static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3588 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003589{
3590 struct l2cap_conf_rsp *rsp = data;
3591 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003592
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003593 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003594
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003595 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003596 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003597 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003598
3599 return ptr - data;
3600}
3601
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003602void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003603{
3604 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003605 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003606 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003607 u8 rsp_code;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003608
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003609 rsp.scid = cpu_to_le16(chan->dcid);
3610 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003611 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3612 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003613
3614 if (chan->hs_hcon)
3615 rsp_code = L2CAP_CREATE_CHAN_RSP;
3616 else
3617 rsp_code = L2CAP_CONN_RSP;
3618
3619 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3620
3621 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003622
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003623 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003624 return;
3625
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003626 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003627 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003628 chan->num_conf_req++;
3629}
3630
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003631static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003632{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003633 int type, olen;
3634 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003635 /* Use sane default values in case a misbehaving remote device
3636 * did not send an RFC or extended window size option.
3637 */
3638 u16 txwin_ext = chan->ack_win;
3639 struct l2cap_conf_rfc rfc = {
3640 .mode = chan->mode,
3641 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3642 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3643 .max_pdu_size = cpu_to_le16(chan->imtu),
3644 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3645 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003646
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003647 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003648
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003649 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003650 return;
3651
3652 while (len >= L2CAP_CONF_OPT_SIZE) {
3653 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3654
Mat Martineauc20f8e32012-07-10 05:47:07 -07003655 switch (type) {
3656 case L2CAP_CONF_RFC:
3657 if (olen == sizeof(rfc))
3658 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003659 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003660 case L2CAP_CONF_EWS:
3661 txwin_ext = val;
3662 break;
3663 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003664 }
3665
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003666 switch (rfc.mode) {
3667 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003668 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3669 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003670 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3671 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3672 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3673 else
3674 chan->ack_win = min_t(u16, chan->ack_win,
3675 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003676 break;
3677 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003678 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003679 }
3680}
3681
Gustavo Padovan2d792812012-10-06 10:07:01 +01003682static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003683 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3684 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003685{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003686 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003687
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003688 if (cmd_len < sizeof(*rej))
3689 return -EPROTO;
3690
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003691 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003692 return 0;
3693
3694 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003695 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003696 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003697
3698 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003699 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003700
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003701 l2cap_conn_start(conn);
3702 }
3703
3704 return 0;
3705}
3706
Mat Martineau17009152012-10-23 15:24:07 -07003707static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3708 struct l2cap_cmd_hdr *cmd,
3709 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003710{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003711 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3712 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003713 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003714 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003715 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003716
3717 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003718 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003719
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003720 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003721
3722 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003723 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003724 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003725 result = L2CAP_CR_BAD_PSM;
3726 goto sendresp;
3727 }
3728
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003729 parent = pchan->sk;
3730
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003731 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003732 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003733
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003734 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003735 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003736 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003737 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003738 result = L2CAP_CR_SEC_BLOCK;
3739 goto response;
3740 }
3741
Linus Torvalds1da177e2005-04-16 15:20:36 -07003742 result = L2CAP_CR_NO_MEM;
3743
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003744 /* Check if we already have channel with that dcid */
3745 if (__l2cap_get_chan_by_dcid(conn, scid))
3746 goto response;
3747
Gustavo Padovan80b98022012-05-27 22:27:51 -03003748 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003749 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003750 goto response;
3751
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003752 sk = chan->sk;
3753
Linus Torvalds1da177e2005-04-16 15:20:36 -07003754 hci_conn_hold(conn->hcon);
3755
Linus Torvalds1da177e2005-04-16 15:20:36 -07003756 bacpy(&bt_sk(sk)->src, conn->src);
3757 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003758 chan->psm = psm;
3759 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003760 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003761
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003762 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003763
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003764 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003765
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003766 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003767
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003768 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003769
Marcel Holtmann984947d2009-02-06 23:35:19 +01003770 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003771 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003772 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003773 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003774 result = L2CAP_CR_PEND;
3775 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003776 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003777 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003778 /* Force pending result for AMP controllers.
3779 * The connection will succeed after the
3780 * physical link is up.
3781 */
3782 if (amp_id) {
3783 __l2cap_state_change(chan, BT_CONNECT2);
3784 result = L2CAP_CR_PEND;
3785 } else {
3786 __l2cap_state_change(chan, BT_CONFIG);
3787 result = L2CAP_CR_SUCCESS;
3788 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003789 status = L2CAP_CS_NO_INFO;
3790 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003791 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003792 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003793 result = L2CAP_CR_PEND;
3794 status = L2CAP_CS_AUTHEN_PEND;
3795 }
3796 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003797 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003798 result = L2CAP_CR_PEND;
3799 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003800 }
3801
Linus Torvalds1da177e2005-04-16 15:20:36 -07003802response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003803 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003804 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003805
3806sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003807 rsp.scid = cpu_to_le16(scid);
3808 rsp.dcid = cpu_to_le16(dcid);
3809 rsp.result = cpu_to_le16(result);
3810 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003811 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003812
3813 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3814 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003815 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003816
3817 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3818 conn->info_ident = l2cap_get_ident(conn);
3819
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003820 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003821
Gustavo Padovan2d792812012-10-06 10:07:01 +01003822 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3823 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003824 }
3825
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003826 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003827 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003828 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003829 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003830 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003831 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003832 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003833 }
Mat Martineau17009152012-10-23 15:24:07 -07003834
3835 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003836}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003837
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003838static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003839 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003840{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303841 struct hci_dev *hdev = conn->hcon->hdev;
3842 struct hci_conn *hcon = conn->hcon;
3843
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003844 if (cmd_len < sizeof(struct l2cap_conn_req))
3845 return -EPROTO;
3846
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303847 hci_dev_lock(hdev);
3848 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3849 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3850 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3851 hcon->dst_type, 0, NULL, 0,
3852 hcon->dev_class);
3853 hci_dev_unlock(hdev);
3854
Gustavo Padovan300229f2012-10-12 19:40:40 +08003855 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003856 return 0;
3857}
3858
Mat Martineau5909cf32012-10-23 15:24:08 -07003859static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003860 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3861 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003862{
3863 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3864 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003865 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003866 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003867 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003868
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003869 if (cmd_len < sizeof(*rsp))
3870 return -EPROTO;
3871
Linus Torvalds1da177e2005-04-16 15:20:36 -07003872 scid = __le16_to_cpu(rsp->scid);
3873 dcid = __le16_to_cpu(rsp->dcid);
3874 result = __le16_to_cpu(rsp->result);
3875 status = __le16_to_cpu(rsp->status);
3876
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003877 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 +01003878 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003879
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003880 mutex_lock(&conn->chan_lock);
3881
Linus Torvalds1da177e2005-04-16 15:20:36 -07003882 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003883 chan = __l2cap_get_chan_by_scid(conn, scid);
3884 if (!chan) {
3885 err = -EFAULT;
3886 goto unlock;
3887 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003888 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003889 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3890 if (!chan) {
3891 err = -EFAULT;
3892 goto unlock;
3893 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003894 }
3895
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003896 err = 0;
3897
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003898 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003899
Linus Torvalds1da177e2005-04-16 15:20:36 -07003900 switch (result) {
3901 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003902 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003903 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003904 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003905 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003906
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003907 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003908 break;
3909
Linus Torvalds1da177e2005-04-16 15:20:36 -07003910 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003911 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003912 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003913 break;
3914
3915 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003916 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003917 break;
3918
3919 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003920 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003921 break;
3922 }
3923
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003924 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003925
3926unlock:
3927 mutex_unlock(&conn->chan_lock);
3928
3929 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003930}
3931
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003932static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003933{
3934 /* FCS is enabled only in ERTM or streaming mode, if one or both
3935 * sides request it.
3936 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003937 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003938 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003939 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003940 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003941}
3942
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003943static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3944 u8 ident, u16 flags)
3945{
3946 struct l2cap_conn *conn = chan->conn;
3947
3948 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3949 flags);
3950
3951 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3952 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3953
3954 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
3955 l2cap_build_conf_rsp(chan, data,
3956 L2CAP_CONF_SUCCESS, flags), data);
3957}
3958
Gustavo Padovan2d792812012-10-06 10:07:01 +01003959static inline int l2cap_config_req(struct l2cap_conn *conn,
3960 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3961 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003962{
3963 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3964 u16 dcid, flags;
3965 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003966 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003967 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003968
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003969 if (cmd_len < sizeof(*req))
3970 return -EPROTO;
3971
Linus Torvalds1da177e2005-04-16 15:20:36 -07003972 dcid = __le16_to_cpu(req->dcid);
3973 flags = __le16_to_cpu(req->flags);
3974
3975 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3976
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003977 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003978 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003979 return -ENOENT;
3980
David S. Miller033b1142011-07-21 13:38:42 -07003981 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003982 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003983
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003984 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003985 rej.scid = cpu_to_le16(chan->scid);
3986 rej.dcid = cpu_to_le16(chan->dcid);
3987
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003988 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003989 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003990 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003991 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003992
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003993 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003994 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003995 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003996 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003997 l2cap_build_conf_rsp(chan, rsp,
3998 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003999 goto unlock;
4000 }
4001
4002 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004003 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4004 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004005
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004006 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004007 /* Incomplete config. Send empty response. */
4008 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004009 l2cap_build_conf_rsp(chan, rsp,
4010 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004011 goto unlock;
4012 }
4013
4014 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004015 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004016 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004017 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004018 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004019 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004020
Mat Martineau1500109b2012-10-23 15:24:15 -07004021 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004022 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004023 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004024
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004025 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004026 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004027
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004028 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004029 goto unlock;
4030
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004031 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004032 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004033
Mat Martineau105bdf92012-04-27 16:50:48 -07004034 if (chan->mode == L2CAP_MODE_ERTM ||
4035 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004036 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004037
Mat Martineau3c588192012-04-11 10:48:42 -07004038 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004039 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004040 else
4041 l2cap_chan_ready(chan);
4042
Marcel Holtmann876d9482007-10-20 13:35:42 +02004043 goto unlock;
4044 }
4045
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004046 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004047 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004048 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004049 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004050 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004051 }
4052
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004053 /* Got Conf Rsp PENDING from remote side and asume we sent
4054 Conf Rsp PENDING in the code above */
4055 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004056 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004057
4058 /* check compatibility */
4059
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004060 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004061 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004062 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4063 else
4064 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004065 }
4066
Linus Torvalds1da177e2005-04-16 15:20:36 -07004067unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004068 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004069 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004070}
4071
Gustavo Padovan2d792812012-10-06 10:07:01 +01004072static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004073 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4074 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004075{
4076 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4077 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004078 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004079 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004080 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004081
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004082 if (cmd_len < sizeof(*rsp))
4083 return -EPROTO;
4084
Linus Torvalds1da177e2005-04-16 15:20:36 -07004085 scid = __le16_to_cpu(rsp->scid);
4086 flags = __le16_to_cpu(rsp->flags);
4087 result = __le16_to_cpu(rsp->result);
4088
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004089 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4090 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004091
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004092 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004093 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004094 return 0;
4095
4096 switch (result) {
4097 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004098 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004099 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004100 break;
4101
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004102 case L2CAP_CONF_PENDING:
4103 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4104
4105 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4106 char buf[64];
4107
4108 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004109 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004110 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004111 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004112 goto done;
4113 }
4114
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004115 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004116 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4117 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004118 } else {
4119 if (l2cap_check_efs(chan)) {
4120 amp_create_logical_link(chan);
4121 chan->ident = cmd->ident;
4122 }
4123 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004124 }
4125 goto done;
4126
Linus Torvalds1da177e2005-04-16 15:20:36 -07004127 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004128 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004129 char req[64];
4130
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004131 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004132 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004133 goto done;
4134 }
4135
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004136 /* throw out any old stored conf requests */
4137 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004138 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004139 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004140 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004141 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004142 goto done;
4143 }
4144
4145 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004146 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004147 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004148 if (result != L2CAP_CONF_SUCCESS)
4149 goto done;
4150 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004151 }
4152
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004153 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004154 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004155
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004156 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004157 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004158 goto done;
4159 }
4160
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004161 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004162 goto done;
4163
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004164 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004165
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004166 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004167 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004168
Mat Martineau105bdf92012-04-27 16:50:48 -07004169 if (chan->mode == L2CAP_MODE_ERTM ||
4170 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004171 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004172
Mat Martineau3c588192012-04-11 10:48:42 -07004173 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004174 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004175 else
4176 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004177 }
4178
4179done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004180 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004181 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004182}
4183
Gustavo Padovan2d792812012-10-06 10:07:01 +01004184static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004185 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4186 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004187{
4188 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4189 struct l2cap_disconn_rsp rsp;
4190 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004191 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004192 struct sock *sk;
4193
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004194 if (cmd_len != sizeof(*req))
4195 return -EPROTO;
4196
Linus Torvalds1da177e2005-04-16 15:20:36 -07004197 scid = __le16_to_cpu(req->scid);
4198 dcid = __le16_to_cpu(req->dcid);
4199
4200 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4201
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004202 mutex_lock(&conn->chan_lock);
4203
4204 chan = __l2cap_get_chan_by_scid(conn, dcid);
4205 if (!chan) {
4206 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004207 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004208 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004209
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004210 l2cap_chan_lock(chan);
4211
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004212 sk = chan->sk;
4213
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004214 rsp.dcid = cpu_to_le16(chan->scid);
4215 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004216 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4217
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004218 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004219 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004220 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004221
Mat Martineau61d6ef32012-04-27 16:50:50 -07004222 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004223 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004224
4225 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004226
Gustavo Padovan80b98022012-05-27 22:27:51 -03004227 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004228 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004229
4230 mutex_unlock(&conn->chan_lock);
4231
Linus Torvalds1da177e2005-04-16 15:20:36 -07004232 return 0;
4233}
4234
Gustavo Padovan2d792812012-10-06 10:07:01 +01004235static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004236 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4237 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004238{
4239 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4240 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004241 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004242
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004243 if (cmd_len != sizeof(*rsp))
4244 return -EPROTO;
4245
Linus Torvalds1da177e2005-04-16 15:20:36 -07004246 scid = __le16_to_cpu(rsp->scid);
4247 dcid = __le16_to_cpu(rsp->dcid);
4248
4249 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4250
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004251 mutex_lock(&conn->chan_lock);
4252
4253 chan = __l2cap_get_chan_by_scid(conn, scid);
4254 if (!chan) {
4255 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004256 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004257 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004258
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004259 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004260
Mat Martineau61d6ef32012-04-27 16:50:50 -07004261 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004262 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004263
4264 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004265
Gustavo Padovan80b98022012-05-27 22:27:51 -03004266 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004267 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004268
4269 mutex_unlock(&conn->chan_lock);
4270
Linus Torvalds1da177e2005-04-16 15:20:36 -07004271 return 0;
4272}
4273
Gustavo Padovan2d792812012-10-06 10:07:01 +01004274static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004275 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4276 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004277{
4278 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004279 u16 type;
4280
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004281 if (cmd_len != sizeof(*req))
4282 return -EPROTO;
4283
Linus Torvalds1da177e2005-04-16 15:20:36 -07004284 type = __le16_to_cpu(req->type);
4285
4286 BT_DBG("type 0x%4.4x", type);
4287
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004288 if (type == L2CAP_IT_FEAT_MASK) {
4289 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004290 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004291 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004292 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4293 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004294 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004295 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004296 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004297 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004298 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004299 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004300
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004301 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004302 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4303 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004304 } else if (type == L2CAP_IT_FIXED_CHAN) {
4305 u8 buf[12];
4306 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004307
4308 if (enable_hs)
4309 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4310 else
4311 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4312
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004313 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4314 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004315 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004316 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4317 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004318 } else {
4319 struct l2cap_info_rsp rsp;
4320 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004321 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004322 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4323 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004324 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004325
4326 return 0;
4327}
4328
Gustavo Padovan2d792812012-10-06 10:07:01 +01004329static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004330 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4331 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004332{
4333 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4334 u16 type, result;
4335
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004336 if (cmd_len != sizeof(*rsp))
4337 return -EPROTO;
4338
Linus Torvalds1da177e2005-04-16 15:20:36 -07004339 type = __le16_to_cpu(rsp->type);
4340 result = __le16_to_cpu(rsp->result);
4341
4342 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4343
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004344 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4345 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004346 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004347 return 0;
4348
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004349 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004350
Ville Tervoadb08ed2010-08-04 09:43:33 +03004351 if (result != L2CAP_IR_SUCCESS) {
4352 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4353 conn->info_ident = 0;
4354
4355 l2cap_conn_start(conn);
4356
4357 return 0;
4358 }
4359
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004360 switch (type) {
4361 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004362 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004363
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004364 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004365 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004366 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004367
4368 conn->info_ident = l2cap_get_ident(conn);
4369
4370 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004371 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004372 } else {
4373 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4374 conn->info_ident = 0;
4375
4376 l2cap_conn_start(conn);
4377 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004378 break;
4379
4380 case L2CAP_IT_FIXED_CHAN:
4381 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004382 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004383 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004384
4385 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004386 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004387 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004388
Linus Torvalds1da177e2005-04-16 15:20:36 -07004389 return 0;
4390}
4391
Mat Martineau17009152012-10-23 15:24:07 -07004392static int l2cap_create_channel_req(struct l2cap_conn *conn,
4393 struct l2cap_cmd_hdr *cmd,
4394 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004395{
4396 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004397 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004398 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004399 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004400 u16 psm, scid;
4401
4402 if (cmd_len != sizeof(*req))
4403 return -EPROTO;
4404
4405 if (!enable_hs)
4406 return -EINVAL;
4407
4408 psm = le16_to_cpu(req->psm);
4409 scid = le16_to_cpu(req->scid);
4410
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004411 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 -07004412
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004413 /* For controller id 0 make BR/EDR connection */
4414 if (req->amp_id == HCI_BREDR_ID) {
4415 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4416 req->amp_id);
4417 return 0;
4418 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004419
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004420 /* Validate AMP controller id */
4421 hdev = hci_dev_get(req->amp_id);
4422 if (!hdev)
4423 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004424
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004425 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004426 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004427 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004428 }
4429
4430 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4431 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004432 if (chan) {
4433 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4434 struct hci_conn *hs_hcon;
4435
4436 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, conn->dst);
4437 if (!hs_hcon) {
4438 hci_dev_put(hdev);
4439 return -EFAULT;
4440 }
4441
4442 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4443
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004444 mgr->bredr_chan = chan;
4445 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004446 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004447 conn->mtu = hdev->block_mtu;
4448 }
4449
4450 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004451
4452 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004453
4454error:
4455 rsp.dcid = 0;
4456 rsp.scid = cpu_to_le16(scid);
4457 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4458 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4459
4460 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4461 sizeof(rsp), &rsp);
4462
4463 return -EFAULT;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004464}
4465
Mat Martineau8eb200b2012-10-23 15:24:17 -07004466static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4467{
4468 struct l2cap_move_chan_req req;
4469 u8 ident;
4470
4471 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4472
4473 ident = l2cap_get_ident(chan->conn);
4474 chan->ident = ident;
4475
4476 req.icid = cpu_to_le16(chan->scid);
4477 req.dest_amp_id = dest_amp_id;
4478
4479 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4480 &req);
4481
4482 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4483}
4484
Mat Martineau1500109b2012-10-23 15:24:15 -07004485static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004486{
4487 struct l2cap_move_chan_rsp rsp;
4488
Mat Martineau1500109b2012-10-23 15:24:15 -07004489 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004490
Mat Martineau1500109b2012-10-23 15:24:15 -07004491 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004492 rsp.result = cpu_to_le16(result);
4493
Mat Martineau1500109b2012-10-23 15:24:15 -07004494 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4495 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004496}
4497
Mat Martineau5b155ef2012-10-23 15:24:14 -07004498static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004499{
4500 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004501
Mat Martineau5b155ef2012-10-23 15:24:14 -07004502 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004503
Mat Martineau5b155ef2012-10-23 15:24:14 -07004504 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004505
Mat Martineau5b155ef2012-10-23 15:24:14 -07004506 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004507 cfm.result = cpu_to_le16(result);
4508
Mat Martineau5b155ef2012-10-23 15:24:14 -07004509 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4510 sizeof(cfm), &cfm);
4511
4512 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4513}
4514
4515static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4516{
4517 struct l2cap_move_chan_cfm cfm;
4518
4519 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4520
4521 cfm.icid = cpu_to_le16(icid);
4522 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4523
4524 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4525 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004526}
4527
4528static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004529 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004530{
4531 struct l2cap_move_chan_cfm_rsp rsp;
4532
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004533 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004534
4535 rsp.icid = cpu_to_le16(icid);
4536 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4537}
4538
Mat Martineau5f3847a2012-10-23 15:24:12 -07004539static void __release_logical_link(struct l2cap_chan *chan)
4540{
4541 chan->hs_hchan = NULL;
4542 chan->hs_hcon = NULL;
4543
4544 /* Placeholder - release the logical link */
4545}
4546
Mat Martineau1500109b2012-10-23 15:24:15 -07004547static void l2cap_logical_fail(struct l2cap_chan *chan)
4548{
4549 /* Logical link setup failed */
4550 if (chan->state != BT_CONNECTED) {
4551 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004552 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004553 return;
4554 }
4555
4556 switch (chan->move_role) {
4557 case L2CAP_MOVE_ROLE_RESPONDER:
4558 l2cap_move_done(chan);
4559 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4560 break;
4561 case L2CAP_MOVE_ROLE_INITIATOR:
4562 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4563 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4564 /* Remote has only sent pending or
4565 * success responses, clean up
4566 */
4567 l2cap_move_done(chan);
4568 }
4569
4570 /* Other amp move states imply that the move
4571 * has already aborted
4572 */
4573 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4574 break;
4575 }
4576}
4577
4578static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4579 struct hci_chan *hchan)
4580{
4581 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004582
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004583 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004584 chan->hs_hcon->l2cap_data = chan->conn;
4585
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004586 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004587
4588 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004589 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004590
4591 set_default_fcs(chan);
4592
4593 err = l2cap_ertm_init(chan);
4594 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004595 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004596 else
4597 l2cap_chan_ready(chan);
4598 }
4599}
4600
4601static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4602 struct hci_chan *hchan)
4603{
4604 chan->hs_hcon = hchan->conn;
4605 chan->hs_hcon->l2cap_data = chan->conn;
4606
4607 BT_DBG("move_state %d", chan->move_state);
4608
4609 switch (chan->move_state) {
4610 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4611 /* Move confirm will be sent after a success
4612 * response is received
4613 */
4614 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4615 break;
4616 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4617 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4618 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4619 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4620 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4621 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4622 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4623 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4624 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4625 }
4626 break;
4627 default:
4628 /* Move was not in expected state, free the channel */
4629 __release_logical_link(chan);
4630
4631 chan->move_state = L2CAP_MOVE_STABLE;
4632 }
4633}
4634
4635/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004636void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4637 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004638{
Mat Martineau1500109b2012-10-23 15:24:15 -07004639 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4640
4641 if (status) {
4642 l2cap_logical_fail(chan);
4643 __release_logical_link(chan);
4644 return;
4645 }
4646
4647 if (chan->state != BT_CONNECTED) {
4648 /* Ignore logical link if channel is on BR/EDR */
4649 if (chan->local_amp_id)
4650 l2cap_logical_finish_create(chan, hchan);
4651 } else {
4652 l2cap_logical_finish_move(chan, hchan);
4653 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004654}
4655
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004656void l2cap_move_start(struct l2cap_chan *chan)
4657{
4658 BT_DBG("chan %p", chan);
4659
4660 if (chan->local_amp_id == HCI_BREDR_ID) {
4661 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4662 return;
4663 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4664 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4665 /* Placeholder - start physical link setup */
4666 } else {
4667 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4668 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4669 chan->move_id = 0;
4670 l2cap_move_setup(chan);
4671 l2cap_send_move_chan_req(chan, 0);
4672 }
4673}
4674
Mat Martineau8eb200b2012-10-23 15:24:17 -07004675static void l2cap_do_create(struct l2cap_chan *chan, int result,
4676 u8 local_amp_id, u8 remote_amp_id)
4677{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004678 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4679 local_amp_id, remote_amp_id);
4680
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004681 chan->fcs = L2CAP_FCS_NONE;
4682
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004683 /* Outgoing channel on AMP */
4684 if (chan->state == BT_CONNECT) {
4685 if (result == L2CAP_CR_SUCCESS) {
4686 chan->local_amp_id = local_amp_id;
4687 l2cap_send_create_chan_req(chan, remote_amp_id);
4688 } else {
4689 /* Revert to BR/EDR connect */
4690 l2cap_send_conn_req(chan);
4691 }
4692
4693 return;
4694 }
4695
4696 /* Incoming channel on AMP */
4697 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004698 struct l2cap_conn_rsp rsp;
4699 char buf[128];
4700 rsp.scid = cpu_to_le16(chan->dcid);
4701 rsp.dcid = cpu_to_le16(chan->scid);
4702
Mat Martineau8eb200b2012-10-23 15:24:17 -07004703 if (result == L2CAP_CR_SUCCESS) {
4704 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004705 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4706 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004707 } else {
4708 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004709 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4710 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004711 }
4712
4713 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4714 sizeof(rsp), &rsp);
4715
4716 if (result == L2CAP_CR_SUCCESS) {
4717 __l2cap_state_change(chan, BT_CONFIG);
4718 set_bit(CONF_REQ_SENT, &chan->conf_state);
4719 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4720 L2CAP_CONF_REQ,
4721 l2cap_build_conf_req(chan, buf), buf);
4722 chan->num_conf_req++;
4723 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004724 }
4725}
4726
4727static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4728 u8 remote_amp_id)
4729{
4730 l2cap_move_setup(chan);
4731 chan->move_id = local_amp_id;
4732 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4733
4734 l2cap_send_move_chan_req(chan, remote_amp_id);
4735}
4736
4737static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4738{
4739 struct hci_chan *hchan = NULL;
4740
4741 /* Placeholder - get hci_chan for logical link */
4742
4743 if (hchan) {
4744 if (hchan->state == BT_CONNECTED) {
4745 /* Logical link is ready to go */
4746 chan->hs_hcon = hchan->conn;
4747 chan->hs_hcon->l2cap_data = chan->conn;
4748 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4749 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4750
4751 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4752 } else {
4753 /* Wait for logical link to be ready */
4754 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4755 }
4756 } else {
4757 /* Logical link not available */
4758 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4759 }
4760}
4761
4762static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4763{
4764 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4765 u8 rsp_result;
4766 if (result == -EINVAL)
4767 rsp_result = L2CAP_MR_BAD_ID;
4768 else
4769 rsp_result = L2CAP_MR_NOT_ALLOWED;
4770
4771 l2cap_send_move_chan_rsp(chan, rsp_result);
4772 }
4773
4774 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4775 chan->move_state = L2CAP_MOVE_STABLE;
4776
4777 /* Restart data transmission */
4778 l2cap_ertm_send(chan);
4779}
4780
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004781/* Invoke with locked chan */
4782void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004783{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004784 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004785 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004786
Mat Martineau8eb200b2012-10-23 15:24:17 -07004787 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4788 chan, result, local_amp_id, remote_amp_id);
4789
Mat Martineau8eb200b2012-10-23 15:24:17 -07004790 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4791 l2cap_chan_unlock(chan);
4792 return;
4793 }
4794
4795 if (chan->state != BT_CONNECTED) {
4796 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4797 } else if (result != L2CAP_MR_SUCCESS) {
4798 l2cap_do_move_cancel(chan, result);
4799 } else {
4800 switch (chan->move_role) {
4801 case L2CAP_MOVE_ROLE_INITIATOR:
4802 l2cap_do_move_initiate(chan, local_amp_id,
4803 remote_amp_id);
4804 break;
4805 case L2CAP_MOVE_ROLE_RESPONDER:
4806 l2cap_do_move_respond(chan, result);
4807 break;
4808 default:
4809 l2cap_do_move_cancel(chan, result);
4810 break;
4811 }
4812 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004813}
4814
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004815static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004816 struct l2cap_cmd_hdr *cmd,
4817 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004818{
4819 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004820 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004821 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004822 u16 icid = 0;
4823 u16 result = L2CAP_MR_NOT_ALLOWED;
4824
4825 if (cmd_len != sizeof(*req))
4826 return -EPROTO;
4827
4828 icid = le16_to_cpu(req->icid);
4829
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004830 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004831
4832 if (!enable_hs)
4833 return -EINVAL;
4834
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004835 chan = l2cap_get_chan_by_dcid(conn, icid);
4836 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004837 rsp.icid = cpu_to_le16(icid);
4838 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4839 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4840 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004841 return 0;
4842 }
4843
Mat Martineau1500109b2012-10-23 15:24:15 -07004844 chan->ident = cmd->ident;
4845
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004846 if (chan->scid < L2CAP_CID_DYN_START ||
4847 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4848 (chan->mode != L2CAP_MODE_ERTM &&
4849 chan->mode != L2CAP_MODE_STREAMING)) {
4850 result = L2CAP_MR_NOT_ALLOWED;
4851 goto send_move_response;
4852 }
4853
4854 if (chan->local_amp_id == req->dest_amp_id) {
4855 result = L2CAP_MR_SAME_ID;
4856 goto send_move_response;
4857 }
4858
4859 if (req->dest_amp_id) {
4860 struct hci_dev *hdev;
4861 hdev = hci_dev_get(req->dest_amp_id);
4862 if (!hdev || hdev->dev_type != HCI_AMP ||
4863 !test_bit(HCI_UP, &hdev->flags)) {
4864 if (hdev)
4865 hci_dev_put(hdev);
4866
4867 result = L2CAP_MR_BAD_ID;
4868 goto send_move_response;
4869 }
4870 hci_dev_put(hdev);
4871 }
4872
4873 /* Detect a move collision. Only send a collision response
4874 * if this side has "lost", otherwise proceed with the move.
4875 * The winner has the larger bd_addr.
4876 */
4877 if ((__chan_is_moving(chan) ||
4878 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
4879 bacmp(conn->src, conn->dst) > 0) {
4880 result = L2CAP_MR_COLLISION;
4881 goto send_move_response;
4882 }
4883
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004884 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4885 l2cap_move_setup(chan);
4886 chan->move_id = req->dest_amp_id;
4887 icid = chan->dcid;
4888
4889 if (!req->dest_amp_id) {
4890 /* Moving to BR/EDR */
4891 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4892 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4893 result = L2CAP_MR_PEND;
4894 } else {
4895 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4896 result = L2CAP_MR_SUCCESS;
4897 }
4898 } else {
4899 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4900 /* Placeholder - uncomment when amp functions are available */
4901 /*amp_accept_physical(chan, req->dest_amp_id);*/
4902 result = L2CAP_MR_PEND;
4903 }
4904
4905send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004906 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004907
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004908 l2cap_chan_unlock(chan);
4909
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004910 return 0;
4911}
4912
Mat Martineau5b155ef2012-10-23 15:24:14 -07004913static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4914{
4915 struct l2cap_chan *chan;
4916 struct hci_chan *hchan = NULL;
4917
4918 chan = l2cap_get_chan_by_scid(conn, icid);
4919 if (!chan) {
4920 l2cap_send_move_chan_cfm_icid(conn, icid);
4921 return;
4922 }
4923
4924 __clear_chan_timer(chan);
4925 if (result == L2CAP_MR_PEND)
4926 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4927
4928 switch (chan->move_state) {
4929 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4930 /* Move confirm will be sent when logical link
4931 * is complete.
4932 */
4933 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4934 break;
4935 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4936 if (result == L2CAP_MR_PEND) {
4937 break;
4938 } else if (test_bit(CONN_LOCAL_BUSY,
4939 &chan->conn_state)) {
4940 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4941 } else {
4942 /* Logical link is up or moving to BR/EDR,
4943 * proceed with move
4944 */
4945 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4946 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4947 }
4948 break;
4949 case L2CAP_MOVE_WAIT_RSP:
4950 /* Moving to AMP */
4951 if (result == L2CAP_MR_SUCCESS) {
4952 /* Remote is ready, send confirm immediately
4953 * after logical link is ready
4954 */
4955 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4956 } else {
4957 /* Both logical link and move success
4958 * are required to confirm
4959 */
4960 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
4961 }
4962
4963 /* Placeholder - get hci_chan for logical link */
4964 if (!hchan) {
4965 /* Logical link not available */
4966 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4967 break;
4968 }
4969
4970 /* If the logical link is not yet connected, do not
4971 * send confirmation.
4972 */
4973 if (hchan->state != BT_CONNECTED)
4974 break;
4975
4976 /* Logical link is already ready to go */
4977
4978 chan->hs_hcon = hchan->conn;
4979 chan->hs_hcon->l2cap_data = chan->conn;
4980
4981 if (result == L2CAP_MR_SUCCESS) {
4982 /* Can confirm now */
4983 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4984 } else {
4985 /* Now only need move success
4986 * to confirm
4987 */
4988 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4989 }
4990
4991 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4992 break;
4993 default:
4994 /* Any other amp move state means the move failed. */
4995 chan->move_id = chan->local_amp_id;
4996 l2cap_move_done(chan);
4997 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4998 }
4999
5000 l2cap_chan_unlock(chan);
5001}
5002
5003static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5004 u16 result)
5005{
5006 struct l2cap_chan *chan;
5007
5008 chan = l2cap_get_chan_by_ident(conn, ident);
5009 if (!chan) {
5010 /* Could not locate channel, icid is best guess */
5011 l2cap_send_move_chan_cfm_icid(conn, icid);
5012 return;
5013 }
5014
5015 __clear_chan_timer(chan);
5016
5017 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5018 if (result == L2CAP_MR_COLLISION) {
5019 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5020 } else {
5021 /* Cleanup - cancel move */
5022 chan->move_id = chan->local_amp_id;
5023 l2cap_move_done(chan);
5024 }
5025 }
5026
5027 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5028
5029 l2cap_chan_unlock(chan);
5030}
5031
5032static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5033 struct l2cap_cmd_hdr *cmd,
5034 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005035{
5036 struct l2cap_move_chan_rsp *rsp = data;
5037 u16 icid, result;
5038
5039 if (cmd_len != sizeof(*rsp))
5040 return -EPROTO;
5041
5042 icid = le16_to_cpu(rsp->icid);
5043 result = le16_to_cpu(rsp->result);
5044
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005045 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005046
Mat Martineau5b155ef2012-10-23 15:24:14 -07005047 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5048 l2cap_move_continue(conn, icid, result);
5049 else
5050 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005051
5052 return 0;
5053}
5054
Mat Martineau5f3847a2012-10-23 15:24:12 -07005055static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5056 struct l2cap_cmd_hdr *cmd,
5057 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005058{
5059 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005060 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005061 u16 icid, result;
5062
5063 if (cmd_len != sizeof(*cfm))
5064 return -EPROTO;
5065
5066 icid = le16_to_cpu(cfm->icid);
5067 result = le16_to_cpu(cfm->result);
5068
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005069 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005070
Mat Martineau5f3847a2012-10-23 15:24:12 -07005071 chan = l2cap_get_chan_by_dcid(conn, icid);
5072 if (!chan) {
5073 /* Spec requires a response even if the icid was not found */
5074 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5075 return 0;
5076 }
5077
5078 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5079 if (result == L2CAP_MC_CONFIRMED) {
5080 chan->local_amp_id = chan->move_id;
5081 if (!chan->local_amp_id)
5082 __release_logical_link(chan);
5083 } else {
5084 chan->move_id = chan->local_amp_id;
5085 }
5086
5087 l2cap_move_done(chan);
5088 }
5089
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005090 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5091
Mat Martineau5f3847a2012-10-23 15:24:12 -07005092 l2cap_chan_unlock(chan);
5093
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005094 return 0;
5095}
5096
5097static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005098 struct l2cap_cmd_hdr *cmd,
5099 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005100{
5101 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005102 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005103 u16 icid;
5104
5105 if (cmd_len != sizeof(*rsp))
5106 return -EPROTO;
5107
5108 icid = le16_to_cpu(rsp->icid);
5109
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005110 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005111
Mat Martineau3fd71a02012-10-23 15:24:16 -07005112 chan = l2cap_get_chan_by_scid(conn, icid);
5113 if (!chan)
5114 return 0;
5115
5116 __clear_chan_timer(chan);
5117
5118 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5119 chan->local_amp_id = chan->move_id;
5120
5121 if (!chan->local_amp_id && chan->hs_hchan)
5122 __release_logical_link(chan);
5123
5124 l2cap_move_done(chan);
5125 }
5126
5127 l2cap_chan_unlock(chan);
5128
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005129 return 0;
5130}
5131
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005132static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005133 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005134{
5135 u16 max_latency;
5136
5137 if (min > max || min < 6 || max > 3200)
5138 return -EINVAL;
5139
5140 if (to_multiplier < 10 || to_multiplier > 3200)
5141 return -EINVAL;
5142
5143 if (max >= to_multiplier * 8)
5144 return -EINVAL;
5145
5146 max_latency = (to_multiplier * 8 / max) - 1;
5147 if (latency > 499 || latency > max_latency)
5148 return -EINVAL;
5149
5150 return 0;
5151}
5152
5153static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005154 struct l2cap_cmd_hdr *cmd,
5155 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005156{
5157 struct hci_conn *hcon = conn->hcon;
5158 struct l2cap_conn_param_update_req *req;
5159 struct l2cap_conn_param_update_rsp rsp;
5160 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005161 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005162
5163 if (!(hcon->link_mode & HCI_LM_MASTER))
5164 return -EINVAL;
5165
5166 cmd_len = __le16_to_cpu(cmd->len);
5167 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5168 return -EPROTO;
5169
5170 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005171 min = __le16_to_cpu(req->min);
5172 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005173 latency = __le16_to_cpu(req->latency);
5174 to_multiplier = __le16_to_cpu(req->to_multiplier);
5175
5176 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 +01005177 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005178
5179 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005180
5181 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5182 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005183 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005184 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005185 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005186
5187 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005188 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005189
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005190 if (!err)
5191 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5192
Claudio Takahaside731152011-02-11 19:28:55 -02005193 return 0;
5194}
5195
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005196static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005197 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5198 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005199{
5200 int err = 0;
5201
5202 switch (cmd->code) {
5203 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005204 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005205 break;
5206
5207 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005208 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005209 break;
5210
5211 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005212 case L2CAP_CREATE_CHAN_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005213 err = l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005214 break;
5215
5216 case L2CAP_CONF_REQ:
5217 err = l2cap_config_req(conn, cmd, cmd_len, data);
5218 break;
5219
5220 case L2CAP_CONF_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005221 err = l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005222 break;
5223
5224 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005225 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005226 break;
5227
5228 case L2CAP_DISCONN_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005229 err = l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005230 break;
5231
5232 case L2CAP_ECHO_REQ:
5233 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5234 break;
5235
5236 case L2CAP_ECHO_RSP:
5237 break;
5238
5239 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005240 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005241 break;
5242
5243 case L2CAP_INFO_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005244 err = l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005245 break;
5246
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005247 case L2CAP_CREATE_CHAN_REQ:
5248 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5249 break;
5250
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005251 case L2CAP_MOVE_CHAN_REQ:
5252 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5253 break;
5254
5255 case L2CAP_MOVE_CHAN_RSP:
5256 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
5257 break;
5258
5259 case L2CAP_MOVE_CHAN_CFM:
5260 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5261 break;
5262
5263 case L2CAP_MOVE_CHAN_CFM_RSP:
5264 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
5265 break;
5266
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005267 default:
5268 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5269 err = -EINVAL;
5270 break;
5271 }
5272
5273 return err;
5274}
5275
5276static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005277 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005278{
5279 switch (cmd->code) {
5280 case L2CAP_COMMAND_REJ:
5281 return 0;
5282
5283 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02005284 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005285
5286 case L2CAP_CONN_PARAM_UPDATE_RSP:
5287 return 0;
5288
5289 default:
5290 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5291 return -EINVAL;
5292 }
5293}
5294
Johan Hedbergc5623552013-04-29 19:35:33 +03005295static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5296 struct sk_buff *skb)
5297{
5298 u8 *data = skb->data;
5299 int len = skb->len;
5300 struct l2cap_cmd_hdr cmd;
5301 int err;
5302
5303 l2cap_raw_recv(conn, skb);
5304
5305 while (len >= L2CAP_CMD_HDR_SIZE) {
5306 u16 cmd_len;
5307 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5308 data += L2CAP_CMD_HDR_SIZE;
5309 len -= L2CAP_CMD_HDR_SIZE;
5310
5311 cmd_len = le16_to_cpu(cmd.len);
5312
5313 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5314 cmd.ident);
5315
5316 if (cmd_len > len || !cmd.ident) {
5317 BT_DBG("corrupted command");
5318 break;
5319 }
5320
5321 err = l2cap_le_sig_cmd(conn, &cmd, data);
5322 if (err) {
5323 struct l2cap_cmd_rej_unk rej;
5324
5325 BT_ERR("Wrong link type (%d)", err);
5326
5327 /* FIXME: Map err to a valid reason */
5328 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
5329 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5330 sizeof(rej), &rej);
5331 }
5332
5333 data += cmd_len;
5334 len -= cmd_len;
5335 }
5336
5337 kfree_skb(skb);
5338}
5339
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005340static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005341 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005342{
5343 u8 *data = skb->data;
5344 int len = skb->len;
5345 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005346 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005347
5348 l2cap_raw_recv(conn, skb);
5349
5350 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005351 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005352 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5353 data += L2CAP_CMD_HDR_SIZE;
5354 len -= L2CAP_CMD_HDR_SIZE;
5355
Al Viro88219a02007-07-29 00:17:25 -07005356 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005357
Gustavo Padovan2d792812012-10-06 10:07:01 +01005358 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5359 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005360
Al Viro88219a02007-07-29 00:17:25 -07005361 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005362 BT_DBG("corrupted command");
5363 break;
5364 }
5365
Johan Hedbergc5623552013-04-29 19:35:33 +03005366 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005367 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005368 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005369
5370 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005371
5372 /* FIXME: Map err to a valid reason */
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005373 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005374 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5375 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005376 }
5377
Al Viro88219a02007-07-29 00:17:25 -07005378 data += cmd_len;
5379 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005380 }
5381
5382 kfree_skb(skb);
5383}
5384
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005385static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005386{
5387 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005388 int hdr_size;
5389
5390 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5391 hdr_size = L2CAP_EXT_HDR_SIZE;
5392 else
5393 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005394
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005395 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005396 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005397 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5398 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5399
5400 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005401 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005402 }
5403 return 0;
5404}
5405
Mat Martineau6ea00482012-05-17 20:53:52 -07005406static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005407{
Mat Martineaue31f7632012-05-17 20:53:41 -07005408 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005409
Mat Martineaue31f7632012-05-17 20:53:41 -07005410 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005411
Mat Martineaue31f7632012-05-17 20:53:41 -07005412 memset(&control, 0, sizeof(control));
5413 control.sframe = 1;
5414 control.final = 1;
5415 control.reqseq = chan->buffer_seq;
5416 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005417
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005418 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005419 control.super = L2CAP_SUPER_RNR;
5420 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005421 }
5422
Mat Martineaue31f7632012-05-17 20:53:41 -07005423 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5424 chan->unacked_frames > 0)
5425 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005426
Mat Martineaue31f7632012-05-17 20:53:41 -07005427 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005428 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005429
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005430 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005431 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5432 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5433 * send it now.
5434 */
5435 control.super = L2CAP_SUPER_RR;
5436 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005437 }
5438}
5439
Gustavo Padovan2d792812012-10-06 10:07:01 +01005440static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5441 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005442{
Mat Martineau84084a32011-07-22 14:54:00 -07005443 /* skb->len reflects data in skb as well as all fragments
5444 * skb->data_len reflects only data in fragments
5445 */
5446 if (!skb_has_frag_list(skb))
5447 skb_shinfo(skb)->frag_list = new_frag;
5448
5449 new_frag->next = NULL;
5450
5451 (*last_frag)->next = new_frag;
5452 *last_frag = new_frag;
5453
5454 skb->len += new_frag->len;
5455 skb->data_len += new_frag->len;
5456 skb->truesize += new_frag->truesize;
5457}
5458
Mat Martineau4b51dae92012-05-17 20:53:37 -07005459static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5460 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005461{
5462 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005463
Mat Martineau4b51dae92012-05-17 20:53:37 -07005464 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005465 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005466 if (chan->sdu)
5467 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005468
Gustavo Padovan80b98022012-05-27 22:27:51 -03005469 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005470 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005471
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005472 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005473 if (chan->sdu)
5474 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005475
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005476 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005477 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005478
Mat Martineau84084a32011-07-22 14:54:00 -07005479 if (chan->sdu_len > chan->imtu) {
5480 err = -EMSGSIZE;
5481 break;
5482 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005483
Mat Martineau84084a32011-07-22 14:54:00 -07005484 if (skb->len >= chan->sdu_len)
5485 break;
5486
5487 chan->sdu = skb;
5488 chan->sdu_last_frag = skb;
5489
5490 skb = NULL;
5491 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005492 break;
5493
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005494 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005495 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005496 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005497
Mat Martineau84084a32011-07-22 14:54:00 -07005498 append_skb_frag(chan->sdu, skb,
5499 &chan->sdu_last_frag);
5500 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005501
Mat Martineau84084a32011-07-22 14:54:00 -07005502 if (chan->sdu->len >= chan->sdu_len)
5503 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005504
Mat Martineau84084a32011-07-22 14:54:00 -07005505 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005506 break;
5507
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005508 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005509 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005510 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005511
Mat Martineau84084a32011-07-22 14:54:00 -07005512 append_skb_frag(chan->sdu, skb,
5513 &chan->sdu_last_frag);
5514 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005515
Mat Martineau84084a32011-07-22 14:54:00 -07005516 if (chan->sdu->len != chan->sdu_len)
5517 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005518
Gustavo Padovan80b98022012-05-27 22:27:51 -03005519 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005520
Mat Martineau84084a32011-07-22 14:54:00 -07005521 if (!err) {
5522 /* Reassembly complete */
5523 chan->sdu = NULL;
5524 chan->sdu_last_frag = NULL;
5525 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005526 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005527 break;
5528 }
5529
Mat Martineau84084a32011-07-22 14:54:00 -07005530 if (err) {
5531 kfree_skb(skb);
5532 kfree_skb(chan->sdu);
5533 chan->sdu = NULL;
5534 chan->sdu_last_frag = NULL;
5535 chan->sdu_len = 0;
5536 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005537
Mat Martineau84084a32011-07-22 14:54:00 -07005538 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005539}
5540
Mat Martineau32b32732012-10-23 15:24:11 -07005541static int l2cap_resegment(struct l2cap_chan *chan)
5542{
5543 /* Placeholder */
5544 return 0;
5545}
5546
Mat Martineaue3281402011-07-07 09:39:02 -07005547void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03005548{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005549 u8 event;
5550
5551 if (chan->mode != L2CAP_MODE_ERTM)
5552 return;
5553
5554 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005555 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005556}
5557
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005558static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5559{
Mat Martineau63838722012-05-17 20:53:45 -07005560 int err = 0;
5561 /* Pass sequential frames to l2cap_reassemble_sdu()
5562 * until a gap is encountered.
5563 */
5564
5565 BT_DBG("chan %p", chan);
5566
5567 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5568 struct sk_buff *skb;
5569 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5570 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5571
5572 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5573
5574 if (!skb)
5575 break;
5576
5577 skb_unlink(skb, &chan->srej_q);
5578 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5579 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5580 if (err)
5581 break;
5582 }
5583
5584 if (skb_queue_empty(&chan->srej_q)) {
5585 chan->rx_state = L2CAP_RX_STATE_RECV;
5586 l2cap_send_ack(chan);
5587 }
5588
5589 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005590}
5591
5592static void l2cap_handle_srej(struct l2cap_chan *chan,
5593 struct l2cap_ctrl *control)
5594{
Mat Martineauf80842a2012-05-17 20:53:46 -07005595 struct sk_buff *skb;
5596
5597 BT_DBG("chan %p, control %p", chan, control);
5598
5599 if (control->reqseq == chan->next_tx_seq) {
5600 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005601 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005602 return;
5603 }
5604
5605 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5606
5607 if (skb == NULL) {
5608 BT_DBG("Seq %d not available for retransmission",
5609 control->reqseq);
5610 return;
5611 }
5612
5613 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5614 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005615 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005616 return;
5617 }
5618
5619 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5620
5621 if (control->poll) {
5622 l2cap_pass_to_tx(chan, control);
5623
5624 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5625 l2cap_retransmit(chan, control);
5626 l2cap_ertm_send(chan);
5627
5628 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5629 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5630 chan->srej_save_reqseq = control->reqseq;
5631 }
5632 } else {
5633 l2cap_pass_to_tx_fbit(chan, control);
5634
5635 if (control->final) {
5636 if (chan->srej_save_reqseq != control->reqseq ||
5637 !test_and_clear_bit(CONN_SREJ_ACT,
5638 &chan->conn_state))
5639 l2cap_retransmit(chan, control);
5640 } else {
5641 l2cap_retransmit(chan, control);
5642 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5643 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5644 chan->srej_save_reqseq = control->reqseq;
5645 }
5646 }
5647 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005648}
5649
5650static void l2cap_handle_rej(struct l2cap_chan *chan,
5651 struct l2cap_ctrl *control)
5652{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005653 struct sk_buff *skb;
5654
5655 BT_DBG("chan %p, control %p", chan, control);
5656
5657 if (control->reqseq == chan->next_tx_seq) {
5658 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005659 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005660 return;
5661 }
5662
5663 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5664
5665 if (chan->max_tx && skb &&
5666 bt_cb(skb)->control.retries >= chan->max_tx) {
5667 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005668 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005669 return;
5670 }
5671
5672 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5673
5674 l2cap_pass_to_tx(chan, control);
5675
5676 if (control->final) {
5677 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5678 l2cap_retransmit_all(chan, control);
5679 } else {
5680 l2cap_retransmit_all(chan, control);
5681 l2cap_ertm_send(chan);
5682 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5683 set_bit(CONN_REJ_ACT, &chan->conn_state);
5684 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005685}
5686
Mat Martineau4b51dae92012-05-17 20:53:37 -07005687static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5688{
5689 BT_DBG("chan %p, txseq %d", chan, txseq);
5690
5691 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5692 chan->expected_tx_seq);
5693
5694 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5695 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005696 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005697 /* See notes below regarding "double poll" and
5698 * invalid packets.
5699 */
5700 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5701 BT_DBG("Invalid/Ignore - after SREJ");
5702 return L2CAP_TXSEQ_INVALID_IGNORE;
5703 } else {
5704 BT_DBG("Invalid - in window after SREJ sent");
5705 return L2CAP_TXSEQ_INVALID;
5706 }
5707 }
5708
5709 if (chan->srej_list.head == txseq) {
5710 BT_DBG("Expected SREJ");
5711 return L2CAP_TXSEQ_EXPECTED_SREJ;
5712 }
5713
5714 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5715 BT_DBG("Duplicate SREJ - txseq already stored");
5716 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5717 }
5718
5719 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5720 BT_DBG("Unexpected SREJ - not requested");
5721 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5722 }
5723 }
5724
5725 if (chan->expected_tx_seq == txseq) {
5726 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5727 chan->tx_win) {
5728 BT_DBG("Invalid - txseq outside tx window");
5729 return L2CAP_TXSEQ_INVALID;
5730 } else {
5731 BT_DBG("Expected");
5732 return L2CAP_TXSEQ_EXPECTED;
5733 }
5734 }
5735
5736 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01005737 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005738 BT_DBG("Duplicate - expected_tx_seq later than txseq");
5739 return L2CAP_TXSEQ_DUPLICATE;
5740 }
5741
5742 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
5743 /* A source of invalid packets is a "double poll" condition,
5744 * where delays cause us to send multiple poll packets. If
5745 * the remote stack receives and processes both polls,
5746 * sequence numbers can wrap around in such a way that a
5747 * resent frame has a sequence number that looks like new data
5748 * with a sequence gap. This would trigger an erroneous SREJ
5749 * request.
5750 *
5751 * Fortunately, this is impossible with a tx window that's
5752 * less than half of the maximum sequence number, which allows
5753 * invalid frames to be safely ignored.
5754 *
5755 * With tx window sizes greater than half of the tx window
5756 * maximum, the frame is invalid and cannot be ignored. This
5757 * causes a disconnect.
5758 */
5759
5760 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5761 BT_DBG("Invalid/Ignore - txseq outside tx window");
5762 return L2CAP_TXSEQ_INVALID_IGNORE;
5763 } else {
5764 BT_DBG("Invalid - txseq outside tx window");
5765 return L2CAP_TXSEQ_INVALID;
5766 }
5767 } else {
5768 BT_DBG("Unexpected - txseq indicates missing frames");
5769 return L2CAP_TXSEQ_UNEXPECTED;
5770 }
5771}
5772
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005773static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5774 struct l2cap_ctrl *control,
5775 struct sk_buff *skb, u8 event)
5776{
5777 int err = 0;
5778 bool skb_in_use = 0;
5779
5780 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5781 event);
5782
5783 switch (event) {
5784 case L2CAP_EV_RECV_IFRAME:
5785 switch (l2cap_classify_txseq(chan, control->txseq)) {
5786 case L2CAP_TXSEQ_EXPECTED:
5787 l2cap_pass_to_tx(chan, control);
5788
5789 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5790 BT_DBG("Busy, discarding expected seq %d",
5791 control->txseq);
5792 break;
5793 }
5794
5795 chan->expected_tx_seq = __next_seq(chan,
5796 control->txseq);
5797
5798 chan->buffer_seq = chan->expected_tx_seq;
5799 skb_in_use = 1;
5800
5801 err = l2cap_reassemble_sdu(chan, skb, control);
5802 if (err)
5803 break;
5804
5805 if (control->final) {
5806 if (!test_and_clear_bit(CONN_REJ_ACT,
5807 &chan->conn_state)) {
5808 control->final = 0;
5809 l2cap_retransmit_all(chan, control);
5810 l2cap_ertm_send(chan);
5811 }
5812 }
5813
5814 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5815 l2cap_send_ack(chan);
5816 break;
5817 case L2CAP_TXSEQ_UNEXPECTED:
5818 l2cap_pass_to_tx(chan, control);
5819
5820 /* Can't issue SREJ frames in the local busy state.
5821 * Drop this frame, it will be seen as missing
5822 * when local busy is exited.
5823 */
5824 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5825 BT_DBG("Busy, discarding unexpected seq %d",
5826 control->txseq);
5827 break;
5828 }
5829
5830 /* There was a gap in the sequence, so an SREJ
5831 * must be sent for each missing frame. The
5832 * current frame is stored for later use.
5833 */
5834 skb_queue_tail(&chan->srej_q, skb);
5835 skb_in_use = 1;
5836 BT_DBG("Queued %p (queue len %d)", skb,
5837 skb_queue_len(&chan->srej_q));
5838
5839 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5840 l2cap_seq_list_clear(&chan->srej_list);
5841 l2cap_send_srej(chan, control->txseq);
5842
5843 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5844 break;
5845 case L2CAP_TXSEQ_DUPLICATE:
5846 l2cap_pass_to_tx(chan, control);
5847 break;
5848 case L2CAP_TXSEQ_INVALID_IGNORE:
5849 break;
5850 case L2CAP_TXSEQ_INVALID:
5851 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005852 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005853 break;
5854 }
5855 break;
5856 case L2CAP_EV_RECV_RR:
5857 l2cap_pass_to_tx(chan, control);
5858 if (control->final) {
5859 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5860
Mat Martineaue6a3ee62012-10-23 15:24:22 -07005861 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
5862 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005863 control->final = 0;
5864 l2cap_retransmit_all(chan, control);
5865 }
5866
5867 l2cap_ertm_send(chan);
5868 } else if (control->poll) {
5869 l2cap_send_i_or_rr_or_rnr(chan);
5870 } else {
5871 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5872 &chan->conn_state) &&
5873 chan->unacked_frames)
5874 __set_retrans_timer(chan);
5875
5876 l2cap_ertm_send(chan);
5877 }
5878 break;
5879 case L2CAP_EV_RECV_RNR:
5880 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5881 l2cap_pass_to_tx(chan, control);
5882 if (control && control->poll) {
5883 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5884 l2cap_send_rr_or_rnr(chan, 0);
5885 }
5886 __clear_retrans_timer(chan);
5887 l2cap_seq_list_clear(&chan->retrans_list);
5888 break;
5889 case L2CAP_EV_RECV_REJ:
5890 l2cap_handle_rej(chan, control);
5891 break;
5892 case L2CAP_EV_RECV_SREJ:
5893 l2cap_handle_srej(chan, control);
5894 break;
5895 default:
5896 break;
5897 }
5898
5899 if (skb && !skb_in_use) {
5900 BT_DBG("Freeing %p", skb);
5901 kfree_skb(skb);
5902 }
5903
5904 return err;
5905}
5906
5907static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5908 struct l2cap_ctrl *control,
5909 struct sk_buff *skb, u8 event)
5910{
5911 int err = 0;
5912 u16 txseq = control->txseq;
5913 bool skb_in_use = 0;
5914
5915 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5916 event);
5917
5918 switch (event) {
5919 case L2CAP_EV_RECV_IFRAME:
5920 switch (l2cap_classify_txseq(chan, txseq)) {
5921 case L2CAP_TXSEQ_EXPECTED:
5922 /* Keep frame for reassembly later */
5923 l2cap_pass_to_tx(chan, control);
5924 skb_queue_tail(&chan->srej_q, skb);
5925 skb_in_use = 1;
5926 BT_DBG("Queued %p (queue len %d)", skb,
5927 skb_queue_len(&chan->srej_q));
5928
5929 chan->expected_tx_seq = __next_seq(chan, txseq);
5930 break;
5931 case L2CAP_TXSEQ_EXPECTED_SREJ:
5932 l2cap_seq_list_pop(&chan->srej_list);
5933
5934 l2cap_pass_to_tx(chan, control);
5935 skb_queue_tail(&chan->srej_q, skb);
5936 skb_in_use = 1;
5937 BT_DBG("Queued %p (queue len %d)", skb,
5938 skb_queue_len(&chan->srej_q));
5939
5940 err = l2cap_rx_queued_iframes(chan);
5941 if (err)
5942 break;
5943
5944 break;
5945 case L2CAP_TXSEQ_UNEXPECTED:
5946 /* Got a frame that can't be reassembled yet.
5947 * Save it for later, and send SREJs to cover
5948 * the missing frames.
5949 */
5950 skb_queue_tail(&chan->srej_q, skb);
5951 skb_in_use = 1;
5952 BT_DBG("Queued %p (queue len %d)", skb,
5953 skb_queue_len(&chan->srej_q));
5954
5955 l2cap_pass_to_tx(chan, control);
5956 l2cap_send_srej(chan, control->txseq);
5957 break;
5958 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
5959 /* This frame was requested with an SREJ, but
5960 * some expected retransmitted frames are
5961 * missing. Request retransmission of missing
5962 * SREJ'd frames.
5963 */
5964 skb_queue_tail(&chan->srej_q, skb);
5965 skb_in_use = 1;
5966 BT_DBG("Queued %p (queue len %d)", skb,
5967 skb_queue_len(&chan->srej_q));
5968
5969 l2cap_pass_to_tx(chan, control);
5970 l2cap_send_srej_list(chan, control->txseq);
5971 break;
5972 case L2CAP_TXSEQ_DUPLICATE_SREJ:
5973 /* We've already queued this frame. Drop this copy. */
5974 l2cap_pass_to_tx(chan, control);
5975 break;
5976 case L2CAP_TXSEQ_DUPLICATE:
5977 /* Expecting a later sequence number, so this frame
5978 * was already received. Ignore it completely.
5979 */
5980 break;
5981 case L2CAP_TXSEQ_INVALID_IGNORE:
5982 break;
5983 case L2CAP_TXSEQ_INVALID:
5984 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005985 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005986 break;
5987 }
5988 break;
5989 case L2CAP_EV_RECV_RR:
5990 l2cap_pass_to_tx(chan, control);
5991 if (control->final) {
5992 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5993
5994 if (!test_and_clear_bit(CONN_REJ_ACT,
5995 &chan->conn_state)) {
5996 control->final = 0;
5997 l2cap_retransmit_all(chan, control);
5998 }
5999
6000 l2cap_ertm_send(chan);
6001 } else if (control->poll) {
6002 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6003 &chan->conn_state) &&
6004 chan->unacked_frames) {
6005 __set_retrans_timer(chan);
6006 }
6007
6008 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6009 l2cap_send_srej_tail(chan);
6010 } else {
6011 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6012 &chan->conn_state) &&
6013 chan->unacked_frames)
6014 __set_retrans_timer(chan);
6015
6016 l2cap_send_ack(chan);
6017 }
6018 break;
6019 case L2CAP_EV_RECV_RNR:
6020 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6021 l2cap_pass_to_tx(chan, control);
6022 if (control->poll) {
6023 l2cap_send_srej_tail(chan);
6024 } else {
6025 struct l2cap_ctrl rr_control;
6026 memset(&rr_control, 0, sizeof(rr_control));
6027 rr_control.sframe = 1;
6028 rr_control.super = L2CAP_SUPER_RR;
6029 rr_control.reqseq = chan->buffer_seq;
6030 l2cap_send_sframe(chan, &rr_control);
6031 }
6032
6033 break;
6034 case L2CAP_EV_RECV_REJ:
6035 l2cap_handle_rej(chan, control);
6036 break;
6037 case L2CAP_EV_RECV_SREJ:
6038 l2cap_handle_srej(chan, control);
6039 break;
6040 }
6041
6042 if (skb && !skb_in_use) {
6043 BT_DBG("Freeing %p", skb);
6044 kfree_skb(skb);
6045 }
6046
6047 return err;
6048}
6049
Mat Martineau32b32732012-10-23 15:24:11 -07006050static int l2cap_finish_move(struct l2cap_chan *chan)
6051{
6052 BT_DBG("chan %p", chan);
6053
6054 chan->rx_state = L2CAP_RX_STATE_RECV;
6055
6056 if (chan->hs_hcon)
6057 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6058 else
6059 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6060
6061 return l2cap_resegment(chan);
6062}
6063
6064static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6065 struct l2cap_ctrl *control,
6066 struct sk_buff *skb, u8 event)
6067{
6068 int err;
6069
6070 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6071 event);
6072
6073 if (!control->poll)
6074 return -EPROTO;
6075
6076 l2cap_process_reqseq(chan, control->reqseq);
6077
6078 if (!skb_queue_empty(&chan->tx_q))
6079 chan->tx_send_head = skb_peek(&chan->tx_q);
6080 else
6081 chan->tx_send_head = NULL;
6082
6083 /* Rewind next_tx_seq to the point expected
6084 * by the receiver.
6085 */
6086 chan->next_tx_seq = control->reqseq;
6087 chan->unacked_frames = 0;
6088
6089 err = l2cap_finish_move(chan);
6090 if (err)
6091 return err;
6092
6093 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6094 l2cap_send_i_or_rr_or_rnr(chan);
6095
6096 if (event == L2CAP_EV_RECV_IFRAME)
6097 return -EPROTO;
6098
6099 return l2cap_rx_state_recv(chan, control, NULL, event);
6100}
6101
6102static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6103 struct l2cap_ctrl *control,
6104 struct sk_buff *skb, u8 event)
6105{
6106 int err;
6107
6108 if (!control->final)
6109 return -EPROTO;
6110
6111 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6112
6113 chan->rx_state = L2CAP_RX_STATE_RECV;
6114 l2cap_process_reqseq(chan, control->reqseq);
6115
6116 if (!skb_queue_empty(&chan->tx_q))
6117 chan->tx_send_head = skb_peek(&chan->tx_q);
6118 else
6119 chan->tx_send_head = NULL;
6120
6121 /* Rewind next_tx_seq to the point expected
6122 * by the receiver.
6123 */
6124 chan->next_tx_seq = control->reqseq;
6125 chan->unacked_frames = 0;
6126
6127 if (chan->hs_hcon)
6128 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6129 else
6130 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6131
6132 err = l2cap_resegment(chan);
6133
6134 if (!err)
6135 err = l2cap_rx_state_recv(chan, control, skb, event);
6136
6137 return err;
6138}
6139
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006140static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6141{
6142 /* Make sure reqseq is for a packet that has been sent but not acked */
6143 u16 unacked;
6144
6145 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6146 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6147}
6148
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006149static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6150 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006151{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006152 int err = 0;
6153
6154 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6155 control, skb, event, chan->rx_state);
6156
6157 if (__valid_reqseq(chan, control->reqseq)) {
6158 switch (chan->rx_state) {
6159 case L2CAP_RX_STATE_RECV:
6160 err = l2cap_rx_state_recv(chan, control, skb, event);
6161 break;
6162 case L2CAP_RX_STATE_SREJ_SENT:
6163 err = l2cap_rx_state_srej_sent(chan, control, skb,
6164 event);
6165 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006166 case L2CAP_RX_STATE_WAIT_P:
6167 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6168 break;
6169 case L2CAP_RX_STATE_WAIT_F:
6170 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6171 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006172 default:
6173 /* shut it down */
6174 break;
6175 }
6176 } else {
6177 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6178 control->reqseq, chan->next_tx_seq,
6179 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006180 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006181 }
6182
6183 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006184}
6185
6186static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6187 struct sk_buff *skb)
6188{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006189 int err = 0;
6190
6191 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6192 chan->rx_state);
6193
6194 if (l2cap_classify_txseq(chan, control->txseq) ==
6195 L2CAP_TXSEQ_EXPECTED) {
6196 l2cap_pass_to_tx(chan, control);
6197
6198 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6199 __next_seq(chan, chan->buffer_seq));
6200
6201 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6202
6203 l2cap_reassemble_sdu(chan, skb, control);
6204 } else {
6205 if (chan->sdu) {
6206 kfree_skb(chan->sdu);
6207 chan->sdu = NULL;
6208 }
6209 chan->sdu_last_frag = NULL;
6210 chan->sdu_len = 0;
6211
6212 if (skb) {
6213 BT_DBG("Freeing %p", skb);
6214 kfree_skb(skb);
6215 }
6216 }
6217
6218 chan->last_acked_seq = control->txseq;
6219 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6220
6221 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006222}
6223
6224static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6225{
6226 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6227 u16 len;
6228 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006229
Mat Martineaub76bbd62012-04-11 10:48:43 -07006230 __unpack_control(chan, skb);
6231
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006232 len = skb->len;
6233
6234 /*
6235 * We can just drop the corrupted I-frame here.
6236 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006237 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006238 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006239 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006240 goto drop;
6241
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006242 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006243 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006244
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006245 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006246 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006247
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006248 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006249 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006250 goto drop;
6251 }
6252
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006253 if (!control->sframe) {
6254 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006255
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006256 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6257 control->sar, control->reqseq, control->final,
6258 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006259
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006260 /* Validate F-bit - F=0 always valid, F=1 only
6261 * valid in TX WAIT_F
6262 */
6263 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006264 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006265
6266 if (chan->mode != L2CAP_MODE_STREAMING) {
6267 event = L2CAP_EV_RECV_IFRAME;
6268 err = l2cap_rx(chan, control, skb, event);
6269 } else {
6270 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006271 }
6272
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006273 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006274 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006275 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006276 const u8 rx_func_to_event[4] = {
6277 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6278 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6279 };
6280
6281 /* Only I-frames are expected in streaming mode */
6282 if (chan->mode == L2CAP_MODE_STREAMING)
6283 goto drop;
6284
6285 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6286 control->reqseq, control->final, control->poll,
6287 control->super);
6288
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006289 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006290 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006291 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006292 goto drop;
6293 }
6294
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006295 /* Validate F and P bits */
6296 if (control->final && (control->poll ||
6297 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6298 goto drop;
6299
6300 event = rx_func_to_event[control->super];
6301 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006302 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006303 }
6304
6305 return 0;
6306
6307drop:
6308 kfree_skb(skb);
6309 return 0;
6310}
6311
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006312static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6313 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006314{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006315 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006316
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006317 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006318 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006319 if (cid == L2CAP_CID_A2MP) {
6320 chan = a2mp_channel_create(conn, skb);
6321 if (!chan) {
6322 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006323 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006324 }
6325
6326 l2cap_chan_lock(chan);
6327 } else {
6328 BT_DBG("unknown cid 0x%4.4x", cid);
6329 /* Drop packet and return */
6330 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006331 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006332 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006333 }
6334
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006335 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006336
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006337 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006338 goto drop;
6339
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006340 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006341 case L2CAP_MODE_BASIC:
6342 /* If socket recv buffers overflows we drop data here
6343 * which is *bad* because L2CAP has to be reliable.
6344 * But we don't have any other choice. L2CAP doesn't
6345 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006346
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006347 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006348 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006349
Gustavo Padovan80b98022012-05-27 22:27:51 -03006350 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006351 goto done;
6352 break;
6353
6354 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006355 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006356 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006357 goto done;
6358
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006359 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006360 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006361 break;
6362 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006363
6364drop:
6365 kfree_skb(skb);
6366
6367done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006368 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006369}
6370
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006371static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6372 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006373{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006374 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006375
Ido Yarivc2287682012-04-20 15:46:07 -03006376 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006377 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006378 goto drop;
6379
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006380 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006381
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006382 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006383 goto drop;
6384
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006385 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006386 goto drop;
6387
Gustavo Padovan80b98022012-05-27 22:27:51 -03006388 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006389 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006390
6391drop:
6392 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006393}
6394
Marcel Holtmann72f78352013-04-23 00:59:00 -07006395static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006396 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006397{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006398 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006399
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006400 chan = l2cap_global_chan_by_scid(0, L2CAP_CID_ATT,
Marcel Holtmann72f78352013-04-23 00:59:00 -07006401 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006402 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006403 goto drop;
6404
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006405 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006406
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006407 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006408 goto drop;
6409
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006410 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006411 goto drop;
6412
Gustavo Padovan80b98022012-05-27 22:27:51 -03006413 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006414 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006415
6416drop:
6417 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006418}
6419
Linus Torvalds1da177e2005-04-16 15:20:36 -07006420static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6421{
6422 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006423 u16 cid, len;
6424 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006425
6426 skb_pull(skb, L2CAP_HDR_SIZE);
6427 cid = __le16_to_cpu(lh->cid);
6428 len = __le16_to_cpu(lh->len);
6429
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006430 if (len != skb->len) {
6431 kfree_skb(skb);
6432 return;
6433 }
6434
Linus Torvalds1da177e2005-04-16 15:20:36 -07006435 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6436
6437 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02006438 case L2CAP_CID_LE_SIGNALING:
Johan Hedbergc5623552013-04-29 19:35:33 +03006439 l2cap_le_sig_channel(conn, skb);
6440 break;
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006441 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006442 l2cap_sig_channel(conn, skb);
6443 break;
6444
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006445 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006446 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006447 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006448 l2cap_conless_channel(conn, psm, skb);
6449 break;
6450
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006451 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006452 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006453 break;
6454
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006455 case L2CAP_CID_SMP:
6456 if (smp_sig_channel(conn, skb))
6457 l2cap_conn_del(conn->hcon, EACCES);
6458 break;
6459
Linus Torvalds1da177e2005-04-16 15:20:36 -07006460 default:
6461 l2cap_data_channel(conn, cid, skb);
6462 break;
6463 }
6464}
6465
6466/* ---- L2CAP interface with lower layer (HCI) ---- */
6467
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006468int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006469{
6470 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006471 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006472
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006473 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006474
6475 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006476 read_lock(&chan_list_lock);
6477 list_for_each_entry(c, &chan_list, global_l) {
6478 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006479
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006480 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006481 continue;
6482
6483 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006484 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006485 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006486 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006487 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006488 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
6489 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006490 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006491 lm2 |= HCI_LM_MASTER;
6492 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006493 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006494 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006495
6496 return exact ? lm1 : lm2;
6497}
6498
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006499void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006500{
Marcel Holtmann01394182006-07-03 10:02:46 +02006501 struct l2cap_conn *conn;
6502
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006503 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006504
Linus Torvalds1da177e2005-04-16 15:20:36 -07006505 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03006506 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006507 if (conn)
6508 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006509 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006510 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006511 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006512}
6513
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006514int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006515{
6516 struct l2cap_conn *conn = hcon->l2cap_data;
6517
6518 BT_DBG("hcon %p", hcon);
6519
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006520 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006521 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006522 return conn->disc_reason;
6523}
6524
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006525void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006526{
6527 BT_DBG("hcon %p reason %d", hcon, reason);
6528
Joe Perchese1750722011-06-29 18:18:29 -07006529 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006530}
6531
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006532static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006533{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006534 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006535 return;
6536
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006537 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006538 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006539 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006540 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006541 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006542 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006543 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006544 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006545 }
6546}
6547
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006548int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006549{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006550 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006551 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006552
Marcel Holtmann01394182006-07-03 10:02:46 +02006553 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006554 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006555
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006556 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006557
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006558 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306559 if (!status && encrypt)
6560 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006561 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006562 }
6563
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006564 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006565
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006566 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006567 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006568
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006569 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6570 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006571
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006572 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6573 l2cap_chan_unlock(chan);
6574 continue;
6575 }
6576
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006577 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006578 if (!status && encrypt) {
6579 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006580 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006581 }
6582
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006583 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006584 continue;
6585 }
6586
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006587 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006588 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006589 continue;
6590 }
6591
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006592 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006593 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03006594 struct sock *sk = chan->sk;
6595
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006596 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03006597 sk->sk_state_change(sk);
6598
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006599 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006600 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006601 continue;
6602 }
6603
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006604 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006605 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006606 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006607 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006608 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006609 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006610 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006611 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006612 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006613 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006614
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006615 lock_sock(sk);
6616
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006617 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006618 if (test_bit(BT_SK_DEFER_SETUP,
6619 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006620 res = L2CAP_CR_PEND;
6621 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006622 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006623 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006624 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006625 res = L2CAP_CR_SUCCESS;
6626 stat = L2CAP_CS_NO_INFO;
6627 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006628 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006629 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006630 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006631 res = L2CAP_CR_SEC_BLOCK;
6632 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006633 }
6634
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006635 release_sock(sk);
6636
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006637 rsp.scid = cpu_to_le16(chan->dcid);
6638 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006639 rsp.result = cpu_to_le16(res);
6640 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006641 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006642 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006643
6644 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6645 res == L2CAP_CR_SUCCESS) {
6646 char buf[128];
6647 set_bit(CONF_REQ_SENT, &chan->conf_state);
6648 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6649 L2CAP_CONF_REQ,
6650 l2cap_build_conf_req(chan, buf),
6651 buf);
6652 chan->num_conf_req++;
6653 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006654 }
6655
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006656 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006657 }
6658
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006659 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006660
Linus Torvalds1da177e2005-04-16 15:20:36 -07006661 return 0;
6662}
6663
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006664int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006665{
6666 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006667 struct l2cap_hdr *hdr;
6668 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006669
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006670 /* For AMP controller do not create l2cap conn */
6671 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6672 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006673
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006674 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03006675 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006676
6677 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006678 goto drop;
6679
6680 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6681
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006682 switch (flags) {
6683 case ACL_START:
6684 case ACL_START_NO_FLUSH:
6685 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006686 if (conn->rx_len) {
6687 BT_ERR("Unexpected start frame (len %d)", skb->len);
6688 kfree_skb(conn->rx_skb);
6689 conn->rx_skb = NULL;
6690 conn->rx_len = 0;
6691 l2cap_conn_unreliable(conn, ECOMM);
6692 }
6693
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006694 /* Start fragment always begin with Basic L2CAP header */
6695 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006696 BT_ERR("Frame is too short (len %d)", skb->len);
6697 l2cap_conn_unreliable(conn, ECOMM);
6698 goto drop;
6699 }
6700
6701 hdr = (struct l2cap_hdr *) skb->data;
6702 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6703
6704 if (len == skb->len) {
6705 /* Complete frame received */
6706 l2cap_recv_frame(conn, skb);
6707 return 0;
6708 }
6709
6710 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6711
6712 if (skb->len > len) {
6713 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006714 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006715 l2cap_conn_unreliable(conn, ECOMM);
6716 goto drop;
6717 }
6718
6719 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006720 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006721 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006722 goto drop;
6723
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006724 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006725 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006726 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006727 break;
6728
6729 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006730 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6731
6732 if (!conn->rx_len) {
6733 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6734 l2cap_conn_unreliable(conn, ECOMM);
6735 goto drop;
6736 }
6737
6738 if (skb->len > conn->rx_len) {
6739 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006740 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006741 kfree_skb(conn->rx_skb);
6742 conn->rx_skb = NULL;
6743 conn->rx_len = 0;
6744 l2cap_conn_unreliable(conn, ECOMM);
6745 goto drop;
6746 }
6747
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006748 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006749 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006750 conn->rx_len -= skb->len;
6751
6752 if (!conn->rx_len) {
6753 /* Complete frame received */
6754 l2cap_recv_frame(conn, conn->rx_skb);
6755 conn->rx_skb = NULL;
6756 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006757 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006758 }
6759
6760drop:
6761 kfree_skb(skb);
6762 return 0;
6763}
6764
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006765static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006766{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006767 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006768
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006769 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006770
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006771 list_for_each_entry(c, &chan_list, global_l) {
6772 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006773
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006774 seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
6775 &bt_sk(sk)->src, &bt_sk(sk)->dst,
6776 c->state, __le16_to_cpu(c->psm),
6777 c->scid, c->dcid, c->imtu, c->omtu,
6778 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006779 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006780
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006781 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006782
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006783 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006784}
6785
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006786static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6787{
6788 return single_open(file, l2cap_debugfs_show, inode->i_private);
6789}
6790
6791static const struct file_operations l2cap_debugfs_fops = {
6792 .open = l2cap_debugfs_open,
6793 .read = seq_read,
6794 .llseek = seq_lseek,
6795 .release = single_release,
6796};
6797
6798static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006799
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006800int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006801{
6802 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006803
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006804 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006805 if (err < 0)
6806 return err;
6807
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006808 if (bt_debugfs) {
Gustavo Padovan2d792812012-10-06 10:07:01 +01006809 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6810 NULL, &l2cap_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006811 if (!l2cap_debugfs)
6812 BT_ERR("Failed to create L2CAP debug file");
6813 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006814
Linus Torvalds1da177e2005-04-16 15:20:36 -07006815 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006816}
6817
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006818void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006819{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006820 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006821 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006822}
6823
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006824module_param(disable_ertm, bool, 0644);
6825MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");