blob: 4803610187ed1c24757734e12032b66ad9754a28 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
Gustavo F. Padovance5706b2010-07-13 11:57:11 -03004 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
Gustavo F. Padovan5d8868f2010-07-16 16:18:39 -03005 Copyright (C) 2010 Google Inc.
Gustavo F. Padovan590051d2011-12-18 13:39:33 -02006 Copyright (C) 2011 ProFUSION Embedded Systems
Mat Martineau422e9252012-04-27 16:50:55 -07007 Copyright (c) 2012 Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07008
9 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License version 2 as
13 published by the Free Software Foundation;
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
18 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090019 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090024 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
25 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070026 SOFTWARE IS DISCLAIMED.
27*/
28
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020029/* Bluetooth L2CAP core. */
Linus Torvalds1da177e2005-04-16 15:20:36 -070030
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/module.h>
32
Marcel Holtmannaef7d972010-03-21 05:27:45 +010033#include <linux/debugfs.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030034#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36#include <net/bluetooth/bluetooth.h>
37#include <net/bluetooth/hci_core.h>
38#include <net/bluetooth/l2cap.h>
Anderson Brigliab501d6a2011-06-07 18:46:31 -030039#include <net/bluetooth/smp.h>
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +030040#include <net/bluetooth/a2mp.h>
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +020041#include <net/bluetooth/amp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
Mat Martineaud1de6d42012-05-17 20:53:55 -070043bool disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020044
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070045static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Mat Martineau50a147c2011-11-02 16:18:34 -070046static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070047
Johannes Bergb5ad8b72011-06-01 08:54:45 +020048static LIST_HEAD(chan_list);
49static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
Linus Torvalds1da177e2005-04-16 15:20:36 -070051static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +010052 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030053static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
Gustavo Padovan2d792812012-10-06 10:07:01 +010054 void *data);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -030055static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +020056static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Gustavo Padovand6603662012-05-21 13:58:22 -030058static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
Gustavo Padovan2d792812012-10-06 10:07:01 +010059 struct sk_buff_head *skbs, u8 event);
Mat Martineau608bcc62012-05-17 20:53:32 -070060
Marcel Holtmann01394182006-07-03 10:02:46 +020061/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030062
Gustavo Padovan2d792812012-10-06 10:07:01 +010063static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
64 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020065{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020066 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030067
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020068 list_for_each_entry(c, &conn->chan_l, list) {
69 if (c->dcid == cid)
70 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020071 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020072 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020073}
74
Gustavo Padovan2d792812012-10-06 10:07:01 +010075static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
76 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020077{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020078 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030079
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020080 list_for_each_entry(c, &conn->chan_l, list) {
81 if (c->scid == cid)
82 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020083 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020084 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020085}
86
87/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -070088 * Returns locked channel. */
Gustavo Padovan2d792812012-10-06 10:07:01 +010089static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
90 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020091{
Gustavo F. Padovan48454072011-03-25 00:22:30 -030092 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030093
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020094 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030095 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -070096 if (c)
97 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020098 mutex_unlock(&conn->chan_lock);
99
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300100 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200101}
102
Mat Martineaub1a130b2012-10-23 15:24:09 -0700103/* Find channel with given DCID.
104 * Returns locked channel.
105 */
106static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
107 u16 cid)
108{
109 struct l2cap_chan *c;
110
111 mutex_lock(&conn->chan_lock);
112 c = __l2cap_get_chan_by_dcid(conn, cid);
113 if (c)
114 l2cap_chan_lock(c);
115 mutex_unlock(&conn->chan_lock);
116
117 return c;
118}
119
Gustavo Padovan2d792812012-10-06 10:07:01 +0100120static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
121 u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200122{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200123 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300124
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200125 list_for_each_entry(c, &conn->chan_l, list) {
126 if (c->ident == ident)
127 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200128 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200129 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200130}
131
Mat Martineau5b155ef2012-10-23 15:24:14 -0700132static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
133 u8 ident)
134{
135 struct l2cap_chan *c;
136
137 mutex_lock(&conn->chan_lock);
138 c = __l2cap_get_chan_by_ident(conn, ident);
139 if (c)
140 l2cap_chan_lock(c);
141 mutex_unlock(&conn->chan_lock);
142
143 return c;
144}
145
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300146static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300147{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300148 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300149
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300150 list_for_each_entry(c, &chan_list, global_l) {
151 if (c->sport == psm && !bacmp(&bt_sk(c->sk)->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100152 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300153 }
Szymon Janc250938c2011-11-16 09:32:22 +0100154 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300155}
156
157int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
158{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300159 int err;
160
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200161 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300162
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300163 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300164 err = -EADDRINUSE;
165 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300166 }
167
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300168 if (psm) {
169 chan->psm = psm;
170 chan->sport = psm;
171 err = 0;
172 } else {
173 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300174
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300175 err = -EINVAL;
176 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300177 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300178 chan->psm = cpu_to_le16(p);
179 chan->sport = cpu_to_le16(p);
180 err = 0;
181 break;
182 }
183 }
184
185done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200186 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300187 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300188}
189
190int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
191{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200192 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300193
194 chan->scid = scid;
195
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200196 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300197
198 return 0;
199}
200
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300201static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200202{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300203 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200204
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300205 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300206 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200207 return cid;
208 }
209
210 return 0;
211}
212
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200213static void __l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300214{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200215 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100216 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200217
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300218 chan->state = state;
Gustavo Padovan80b98022012-05-27 22:27:51 -0300219 chan->ops->state_change(chan, state);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300220}
221
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200222static void l2cap_state_change(struct l2cap_chan *chan, int state)
223{
224 struct sock *sk = chan->sk;
225
226 lock_sock(sk);
227 __l2cap_state_change(chan, state);
228 release_sock(sk);
229}
230
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200231static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err)
232{
233 struct sock *sk = chan->sk;
234
235 sk->sk_err = err;
236}
237
238static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
239{
240 struct sock *sk = chan->sk;
241
242 lock_sock(sk);
243 __l2cap_chan_set_err(chan, err);
244 release_sock(sk);
245}
246
Mat Martineau4239d162012-05-17 20:53:49 -0700247static void __set_retrans_timer(struct l2cap_chan *chan)
248{
249 if (!delayed_work_pending(&chan->monitor_timer) &&
250 chan->retrans_timeout) {
251 l2cap_set_timer(chan, &chan->retrans_timer,
252 msecs_to_jiffies(chan->retrans_timeout));
253 }
254}
255
256static void __set_monitor_timer(struct l2cap_chan *chan)
257{
258 __clear_retrans_timer(chan);
259 if (chan->monitor_timeout) {
260 l2cap_set_timer(chan, &chan->monitor_timer,
261 msecs_to_jiffies(chan->monitor_timeout));
262 }
263}
264
Mat Martineau608bcc62012-05-17 20:53:32 -0700265static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
266 u16 seq)
267{
268 struct sk_buff *skb;
269
270 skb_queue_walk(head, skb) {
271 if (bt_cb(skb)->control.txseq == seq)
272 return skb;
273 }
274
275 return NULL;
276}
277
Mat Martineau3c588192012-04-11 10:48:42 -0700278/* ---- L2CAP sequence number lists ---- */
279
280/* For ERTM, ordered lists of sequence numbers must be tracked for
281 * SREJ requests that are received and for frames that are to be
282 * retransmitted. These seq_list functions implement a singly-linked
283 * list in an array, where membership in the list can also be checked
284 * in constant time. Items can also be added to the tail of the list
285 * and removed from the head in constant time, without further memory
286 * allocs or frees.
287 */
288
289static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
290{
291 size_t alloc_size, i;
292
293 /* Allocated size is a power of 2 to map sequence numbers
294 * (which may be up to 14 bits) in to a smaller array that is
295 * sized for the negotiated ERTM transmit windows.
296 */
297 alloc_size = roundup_pow_of_two(size);
298
299 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
300 if (!seq_list->list)
301 return -ENOMEM;
302
303 seq_list->mask = alloc_size - 1;
304 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
305 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
306 for (i = 0; i < alloc_size; i++)
307 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
308
309 return 0;
310}
311
312static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
313{
314 kfree(seq_list->list);
315}
316
317static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
318 u16 seq)
319{
320 /* Constant-time check for list membership */
321 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
322}
323
324static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
325{
326 u16 mask = seq_list->mask;
327
328 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
329 /* In case someone tries to pop the head of an empty list */
330 return L2CAP_SEQ_LIST_CLEAR;
331 } else if (seq_list->head == seq) {
332 /* Head can be removed in constant time */
333 seq_list->head = seq_list->list[seq & mask];
334 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
335
336 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
337 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
338 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
339 }
340 } else {
341 /* Walk the list to find the sequence number */
342 u16 prev = seq_list->head;
343 while (seq_list->list[prev & mask] != seq) {
344 prev = seq_list->list[prev & mask];
345 if (prev == L2CAP_SEQ_LIST_TAIL)
346 return L2CAP_SEQ_LIST_CLEAR;
347 }
348
349 /* Unlink the number from the list and clear it */
350 seq_list->list[prev & mask] = seq_list->list[seq & mask];
351 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
352 if (seq_list->tail == seq)
353 seq_list->tail = prev;
354 }
355 return seq;
356}
357
358static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
359{
360 /* Remove the head in constant time */
361 return l2cap_seq_list_remove(seq_list, seq_list->head);
362}
363
364static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
365{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300366 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700367
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300368 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
369 return;
370
371 for (i = 0; i <= seq_list->mask; i++)
372 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
373
374 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
375 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700376}
377
378static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
379{
380 u16 mask = seq_list->mask;
381
382 /* All appends happen in constant time */
383
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300384 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
385 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700386
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300387 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
388 seq_list->head = seq;
389 else
390 seq_list->list[seq_list->tail & mask] = seq;
391
392 seq_list->tail = seq;
393 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700394}
395
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300396static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300397{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300398 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100399 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200400 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300401 int reason;
402
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200403 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300404
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200405 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200406 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300407
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300408 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300409 reason = ECONNREFUSED;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300410 else if (chan->state == BT_CONNECT &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100411 chan->sec_level != BT_SECURITY_SDP)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300412 reason = ECONNREFUSED;
413 else
414 reason = ETIMEDOUT;
415
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300416 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300417
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200418 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300419
Gustavo Padovan80b98022012-05-27 22:27:51 -0300420 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200421 mutex_unlock(&conn->chan_lock);
422
Ulisses Furquim371fd832011-12-21 20:02:36 -0200423 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300424}
425
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300426struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200427{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300428 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200429
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300430 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
431 if (!chan)
432 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200433
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200434 mutex_init(&chan->lock);
435
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200436 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300437 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200438 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300439
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300440 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300441
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300442 chan->state = BT_OPEN;
443
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530444 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300445
Mat Martineau28270112012-05-17 21:14:09 -0700446 /* This flag is cleared in l2cap_chan_ready() */
447 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
448
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300449 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100450
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300451 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200452}
453
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530454static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300455{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530456 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
457
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530458 BT_DBG("chan %p", chan);
459
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200460 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300461 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200462 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300463
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530464 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300465}
466
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530467void l2cap_chan_hold(struct l2cap_chan *c)
468{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530469 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530470
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530471 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530472}
473
474void l2cap_chan_put(struct l2cap_chan *c)
475{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530476 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530477
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530478 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530479}
480
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300481void l2cap_chan_set_defaults(struct l2cap_chan *chan)
482{
483 chan->fcs = L2CAP_FCS_CRC16;
484 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
485 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
486 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700487 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300488 chan->sec_level = BT_SECURITY_LOW;
489
490 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
491}
492
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300493void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200494{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300495 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200496 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200497
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200498 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100499
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300500 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200501
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200502 switch (chan->chan_type) {
503 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300504 if (conn->hcon->type == LE_LINK) {
505 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300506 chan->omtu = L2CAP_DEFAULT_MTU;
Johan Hedberg9f22398c2013-04-29 19:35:38 +0300507 if (chan->dcid == L2CAP_CID_ATT)
508 chan->scid = L2CAP_CID_ATT;
509 else
510 chan->scid = l2cap_alloc_cid(conn);
Ville Tervob62f3282011-02-10 22:38:50 -0300511 } else {
512 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300513 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300514 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300515 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200516 break;
517
518 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200519 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300520 chan->scid = L2CAP_CID_CONN_LESS;
521 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300522 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200523 break;
524
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300525 case L2CAP_CHAN_CONN_FIX_A2MP:
526 chan->scid = L2CAP_CID_A2MP;
527 chan->dcid = L2CAP_CID_A2MP;
528 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
529 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
530 break;
531
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200532 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200533 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300534 chan->scid = L2CAP_CID_SIGNALING;
535 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300536 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200537 }
538
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300539 chan->local_id = L2CAP_BESTEFFORT_ID;
540 chan->local_stype = L2CAP_SERV_BESTEFFORT;
541 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
542 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
543 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300544 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300545
Ulisses Furquim371fd832011-12-21 20:02:36 -0200546 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300547
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200548 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200549}
550
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300551void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200552{
553 mutex_lock(&conn->chan_lock);
554 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200555 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200556}
557
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300558void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200559{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300560 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200561
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300562 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200563
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300564 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200565
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900566 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300567 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300568 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200569 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200570
Ulisses Furquim371fd832011-12-21 20:02:36 -0200571 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300572
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300573 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300574
575 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
David Herrmann76a68ba2013-04-06 20:28:37 +0200576 hci_conn_drop(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300577
578 if (mgr && mgr->bredr_chan == chan)
579 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200580 }
581
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200582 if (chan->hs_hchan) {
583 struct hci_chan *hs_hchan = chan->hs_hchan;
584
585 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
586 amp_disconnect_logical_link(hs_hchan);
587 }
588
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100589 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200590
Mat Martineau28270112012-05-17 21:14:09 -0700591 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300592 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300593
Gustavo Padovanee556f62012-05-18 20:22:38 -0300594 switch(chan->mode) {
595 case L2CAP_MODE_BASIC:
596 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300597
Gustavo Padovanee556f62012-05-18 20:22:38 -0300598 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300599 __clear_retrans_timer(chan);
600 __clear_monitor_timer(chan);
601 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300602
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300603 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300604
Mat Martineau3c588192012-04-11 10:48:42 -0700605 l2cap_seq_list_free(&chan->srej_list);
606 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300607
608 /* fall through */
609
610 case L2CAP_MODE_STREAMING:
611 skb_queue_purge(&chan->tx_q);
612 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300613 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300614
615 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200616}
617
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300618void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300619{
620 struct l2cap_conn *conn = chan->conn;
621 struct sock *sk = chan->sk;
622
Gustavo Padovan2d792812012-10-06 10:07:01 +0100623 BT_DBG("chan %p state %s sk %p", chan, state_to_string(chan->state),
624 sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300625
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300626 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300627 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100628 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300629 break;
630
631 case BT_CONNECTED:
632 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300633 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100634 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300635 __set_chan_timer(chan, sk->sk_sndtimeo);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200636 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300637 } else
638 l2cap_chan_del(chan, reason);
639 break;
640
641 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300642 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100643 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300644 struct l2cap_conn_rsp rsp;
645 __u16 result;
646
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300647 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300648 result = L2CAP_CR_SEC_BLOCK;
649 else
650 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300651 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300652
653 rsp.scid = cpu_to_le16(chan->dcid);
654 rsp.dcid = cpu_to_le16(chan->scid);
655 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300656 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300657 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100658 sizeof(rsp), &rsp);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300659 }
660
661 l2cap_chan_del(chan, reason);
662 break;
663
664 case BT_CONNECT:
665 case BT_DISCONN:
666 l2cap_chan_del(chan, reason);
667 break;
668
669 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100670 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300671 break;
672 }
673}
674
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300675static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530676{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300677 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300678 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530679 case BT_SECURITY_HIGH:
680 return HCI_AT_DEDICATED_BONDING_MITM;
681 case BT_SECURITY_MEDIUM:
682 return HCI_AT_DEDICATED_BONDING;
683 default:
684 return HCI_AT_NO_BONDING;
685 }
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +0300686 } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300687 if (chan->sec_level == BT_SECURITY_LOW)
688 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530689
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300690 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530691 return HCI_AT_NO_BONDING_MITM;
692 else
693 return HCI_AT_NO_BONDING;
694 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300695 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530696 case BT_SECURITY_HIGH:
697 return HCI_AT_GENERAL_BONDING_MITM;
698 case BT_SECURITY_MEDIUM:
699 return HCI_AT_GENERAL_BONDING;
700 default:
701 return HCI_AT_NO_BONDING;
702 }
703 }
704}
705
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200706/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200707int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200708{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300709 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100710 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200711
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300712 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100713
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300714 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200715}
716
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200717static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200718{
719 u8 id;
720
721 /* Get next available identificator.
722 * 1 - 128 are used by kernel.
723 * 129 - 199 are reserved.
724 * 200 - 254 are used by utilities like l2ping, etc.
725 */
726
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200727 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200728
729 if (++conn->tx_ident > 128)
730 conn->tx_ident = 1;
731
732 id = conn->tx_ident;
733
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200734 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200735
736 return id;
737}
738
Gustavo Padovan2d792812012-10-06 10:07:01 +0100739static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
740 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200741{
742 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200743 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200744
745 BT_DBG("code 0x%2.2x", code);
746
747 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300748 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200749
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200750 if (lmp_no_flush_capable(conn->hcon->hdev))
751 flags = ACL_START_NO_FLUSH;
752 else
753 flags = ACL_START;
754
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700755 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200756 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700757
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200758 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200759}
760
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700761static bool __chan_is_moving(struct l2cap_chan *chan)
762{
763 return chan->move_state != L2CAP_MOVE_STABLE &&
764 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
765}
766
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200767static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
768{
769 struct hci_conn *hcon = chan->conn->hcon;
770 u16 flags;
771
772 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100773 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200774
Mat Martineaud5f8a752012-10-23 15:24:18 -0700775 if (chan->hs_hcon && !__chan_is_moving(chan)) {
776 if (chan->hs_hchan)
777 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
778 else
779 kfree_skb(skb);
780
781 return;
782 }
783
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200784 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100785 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200786 flags = ACL_START_NO_FLUSH;
787 else
788 flags = ACL_START;
789
790 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
791 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792}
793
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700794static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
795{
796 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
797 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
798
799 if (enh & L2CAP_CTRL_FRAME_TYPE) {
800 /* S-Frame */
801 control->sframe = 1;
802 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
803 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
804
805 control->sar = 0;
806 control->txseq = 0;
807 } else {
808 /* I-Frame */
809 control->sframe = 0;
810 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
811 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
812
813 control->poll = 0;
814 control->super = 0;
815 }
816}
817
818static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
819{
820 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
821 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
822
823 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
824 /* S-Frame */
825 control->sframe = 1;
826 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
827 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
828
829 control->sar = 0;
830 control->txseq = 0;
831 } else {
832 /* I-Frame */
833 control->sframe = 0;
834 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
835 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
836
837 control->poll = 0;
838 control->super = 0;
839 }
840}
841
842static inline void __unpack_control(struct l2cap_chan *chan,
843 struct sk_buff *skb)
844{
845 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
846 __unpack_extended_control(get_unaligned_le32(skb->data),
847 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700848 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700849 } else {
850 __unpack_enhanced_control(get_unaligned_le16(skb->data),
851 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700852 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700853 }
854}
855
856static u32 __pack_extended_control(struct l2cap_ctrl *control)
857{
858 u32 packed;
859
860 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
861 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
862
863 if (control->sframe) {
864 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
865 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
866 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
867 } else {
868 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
869 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
870 }
871
872 return packed;
873}
874
875static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
876{
877 u16 packed;
878
879 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
880 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
881
882 if (control->sframe) {
883 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
884 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
885 packed |= L2CAP_CTRL_FRAME_TYPE;
886 } else {
887 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
888 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
889 }
890
891 return packed;
892}
893
894static inline void __pack_control(struct l2cap_chan *chan,
895 struct l2cap_ctrl *control,
896 struct sk_buff *skb)
897{
898 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
899 put_unaligned_le32(__pack_extended_control(control),
900 skb->data + L2CAP_HDR_SIZE);
901 } else {
902 put_unaligned_le16(__pack_enhanced_control(control),
903 skb->data + L2CAP_HDR_SIZE);
904 }
905}
906
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300907static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
908{
909 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
910 return L2CAP_EXT_HDR_SIZE;
911 else
912 return L2CAP_ENH_HDR_SIZE;
913}
914
Mat Martineaua67d7f62012-05-17 20:53:35 -0700915static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
916 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300917{
918 struct sk_buff *skb;
919 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300920 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300921
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300922 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300923 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300924
Mat Martineaua67d7f62012-05-17 20:53:35 -0700925 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300926
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300927 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700928 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300929
930 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300931 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300932 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300933
Mat Martineaua67d7f62012-05-17 20:53:35 -0700934 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
935 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
936 else
937 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300938
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300939 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700940 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300941 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300942 }
943
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200944 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700945 return skb;
946}
947
948static void l2cap_send_sframe(struct l2cap_chan *chan,
949 struct l2cap_ctrl *control)
950{
951 struct sk_buff *skb;
952 u32 control_field;
953
954 BT_DBG("chan %p, control %p", chan, control);
955
956 if (!control->sframe)
957 return;
958
Mat Martineaub99e13a2012-10-23 15:24:19 -0700959 if (__chan_is_moving(chan))
960 return;
961
Mat Martineaua67d7f62012-05-17 20:53:35 -0700962 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
963 !control->poll)
964 control->final = 1;
965
966 if (control->super == L2CAP_SUPER_RR)
967 clear_bit(CONN_RNR_SENT, &chan->conn_state);
968 else if (control->super == L2CAP_SUPER_RNR)
969 set_bit(CONN_RNR_SENT, &chan->conn_state);
970
971 if (control->super != L2CAP_SUPER_SREJ) {
972 chan->last_acked_seq = control->reqseq;
973 __clear_ack_timer(chan);
974 }
975
976 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
977 control->final, control->poll, control->super);
978
979 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
980 control_field = __pack_extended_control(control);
981 else
982 control_field = __pack_enhanced_control(control);
983
984 skb = l2cap_create_sframe_pdu(chan, control_field);
985 if (!IS_ERR(skb))
986 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300987}
988
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700989static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300990{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700991 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300992
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700993 BT_DBG("chan %p, poll %d", chan, poll);
994
995 memset(&control, 0, sizeof(control));
996 control.sframe = 1;
997 control.poll = poll;
998
999 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
1000 control.super = L2CAP_SUPER_RNR;
1001 else
1002 control.super = L2CAP_SUPER_RR;
1003
1004 control.reqseq = chan->buffer_seq;
1005 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001006}
1007
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001008static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001009{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001010 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001011}
1012
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001013static bool __amp_capable(struct l2cap_chan *chan)
1014{
1015 struct l2cap_conn *conn = chan->conn;
1016
1017 if (enable_hs &&
Andrei Emeltchenko5d054162012-11-29 17:46:05 +02001018 hci_amp_capable() &&
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001019 chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED &&
1020 conn->fixed_chan_mask & L2CAP_FC_A2MP)
1021 return true;
1022 else
1023 return false;
1024}
1025
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001026static bool l2cap_check_efs(struct l2cap_chan *chan)
1027{
1028 /* Check EFS parameters */
1029 return true;
1030}
1031
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001032void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001033{
1034 struct l2cap_conn *conn = chan->conn;
1035 struct l2cap_conn_req req;
1036
1037 req.scid = cpu_to_le16(chan->scid);
1038 req.psm = chan->psm;
1039
1040 chan->ident = l2cap_get_ident(conn);
1041
1042 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1043
1044 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1045}
1046
Mat Martineau8eb200b2012-10-23 15:24:17 -07001047static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1048{
1049 struct l2cap_create_chan_req req;
1050 req.scid = cpu_to_le16(chan->scid);
1051 req.psm = chan->psm;
1052 req.amp_id = amp_id;
1053
1054 chan->ident = l2cap_get_ident(chan->conn);
1055
1056 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1057 sizeof(req), &req);
1058}
1059
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001060static void l2cap_move_setup(struct l2cap_chan *chan)
1061{
1062 struct sk_buff *skb;
1063
1064 BT_DBG("chan %p", chan);
1065
1066 if (chan->mode != L2CAP_MODE_ERTM)
1067 return;
1068
1069 __clear_retrans_timer(chan);
1070 __clear_monitor_timer(chan);
1071 __clear_ack_timer(chan);
1072
1073 chan->retry_count = 0;
1074 skb_queue_walk(&chan->tx_q, skb) {
1075 if (bt_cb(skb)->control.retries)
1076 bt_cb(skb)->control.retries = 1;
1077 else
1078 break;
1079 }
1080
1081 chan->expected_tx_seq = chan->buffer_seq;
1082
1083 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1084 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1085 l2cap_seq_list_clear(&chan->retrans_list);
1086 l2cap_seq_list_clear(&chan->srej_list);
1087 skb_queue_purge(&chan->srej_q);
1088
1089 chan->tx_state = L2CAP_TX_STATE_XMIT;
1090 chan->rx_state = L2CAP_RX_STATE_MOVE;
1091
1092 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1093}
1094
Mat Martineau5f3847a2012-10-23 15:24:12 -07001095static void l2cap_move_done(struct l2cap_chan *chan)
1096{
1097 u8 move_role = chan->move_role;
1098 BT_DBG("chan %p", chan);
1099
1100 chan->move_state = L2CAP_MOVE_STABLE;
1101 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1102
1103 if (chan->mode != L2CAP_MODE_ERTM)
1104 return;
1105
1106 switch (move_role) {
1107 case L2CAP_MOVE_ROLE_INITIATOR:
1108 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1109 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1110 break;
1111 case L2CAP_MOVE_ROLE_RESPONDER:
1112 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1113 break;
1114 }
1115}
1116
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001117static void l2cap_chan_ready(struct l2cap_chan *chan)
1118{
Mat Martineau28270112012-05-17 21:14:09 -07001119 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001120 chan->conf_state = 0;
1121 __clear_chan_timer(chan);
1122
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001123 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001124
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001125 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001126}
1127
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001128static void l2cap_start_connection(struct l2cap_chan *chan)
1129{
1130 if (__amp_capable(chan)) {
1131 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1132 a2mp_discover_amp(chan);
1133 } else {
1134 l2cap_send_conn_req(chan);
1135 }
1136}
1137
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001138static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001139{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001140 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001141
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001142 if (conn->hcon->type == LE_LINK) {
1143 l2cap_chan_ready(chan);
1144 return;
1145 }
1146
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001147 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001148 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1149 return;
1150
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001151 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001152 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001153 l2cap_start_connection(chan);
1154 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001155 } else {
1156 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001157 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001158
1159 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1160 conn->info_ident = l2cap_get_ident(conn);
1161
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001162 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001163
Gustavo Padovan2d792812012-10-06 10:07:01 +01001164 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1165 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001166 }
1167}
1168
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001169static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1170{
1171 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001172 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001173 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1174
1175 switch (mode) {
1176 case L2CAP_MODE_ERTM:
1177 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1178 case L2CAP_MODE_STREAMING:
1179 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1180 default:
1181 return 0x00;
1182 }
1183}
1184
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001185static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001186{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001187 struct sock *sk = chan->sk;
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001188 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001189 struct l2cap_disconn_req req;
1190
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001191 if (!conn)
1192 return;
1193
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001194 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001195 __clear_retrans_timer(chan);
1196 __clear_monitor_timer(chan);
1197 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001198 }
1199
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001200 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001201 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001202 return;
1203 }
1204
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001205 req.dcid = cpu_to_le16(chan->dcid);
1206 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001207 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1208 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001209
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001210 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001211 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001212 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001213 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001214}
1215
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001217static void l2cap_conn_start(struct l2cap_conn *conn)
1218{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001219 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001220
1221 BT_DBG("conn %p", conn);
1222
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001223 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001224
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001225 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001226 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001227
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001228 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001229
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001230 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001231 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001232 continue;
1233 }
1234
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001235 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001236 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001237 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001238 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001239 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001240 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001241
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001242 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001243 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001244 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001245 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001246 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001247 continue;
1248 }
1249
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001250 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001251
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001252 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001253 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001254 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001255 rsp.scid = cpu_to_le16(chan->dcid);
1256 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001257
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001258 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001259 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001260 if (test_bit(BT_SK_DEFER_SETUP,
1261 &bt_sk(sk)->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001262 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1263 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001264 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001265
1266 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001267 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001268 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1269 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001270 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001271 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001272 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001273 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1274 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001275 }
1276
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001277 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001278 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001279
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001280 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001281 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001282 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001283 continue;
1284 }
1285
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001286 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001287 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001288 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001289 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001290 }
1291
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001292 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001293 }
1294
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001295 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001296}
1297
Ido Yarivc2287682012-04-20 15:46:07 -03001298/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001299 * Returns closest match, locked.
1300 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001301static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001302 bdaddr_t *src,
1303 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001304{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001305 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001306
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001307 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001308
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001309 list_for_each_entry(c, &chan_list, global_l) {
1310 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001311
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001312 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001313 continue;
1314
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001315 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001316 int src_match, dst_match;
1317 int src_any, dst_any;
1318
Ville Tervob62f3282011-02-10 22:38:50 -03001319 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001320 src_match = !bacmp(&bt_sk(sk)->src, src);
1321 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1322 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001323 read_unlock(&chan_list_lock);
1324 return c;
1325 }
Ville Tervob62f3282011-02-10 22:38:50 -03001326
1327 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001328 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1329 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1330 if ((src_match && dst_any) || (src_any && dst_match) ||
1331 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001332 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001333 }
1334 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001335
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001336 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001337
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001338 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001339}
1340
1341static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1342{
Gustavo F. Padovanc916fbe2011-04-04 16:00:55 -03001343 struct sock *parent, *sk;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001344 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001345
1346 BT_DBG("");
1347
1348 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001349 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Ido Yarivc2287682012-04-20 15:46:07 -03001350 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001351 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001352 return;
1353
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001354 parent = pchan->sk;
1355
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001356 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001357
Gustavo Padovan80b98022012-05-27 22:27:51 -03001358 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001359 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001360 goto clean;
1361
Johan Hedberg9f22398c2013-04-29 19:35:38 +03001362 chan->dcid = L2CAP_CID_ATT;
1363
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001364 sk = chan->sk;
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001365
Ville Tervob62f3282011-02-10 22:38:50 -03001366 hci_conn_hold(conn->hcon);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001367 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
Ville Tervob62f3282011-02-10 22:38:50 -03001368
Ville Tervob62f3282011-02-10 22:38:50 -03001369 bacpy(&bt_sk(sk)->src, conn->src);
1370 bacpy(&bt_sk(sk)->dst, conn->dst);
1371
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001372 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001373
Gustavo Padovan6754e0d2012-05-25 09:30:56 -03001374 l2cap_chan_ready(chan);
Ville Tervob62f3282011-02-10 22:38:50 -03001375
Ville Tervob62f3282011-02-10 22:38:50 -03001376clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001377 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001378}
1379
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001380static void l2cap_conn_ready(struct l2cap_conn *conn)
1381{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001382 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001383 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001384
1385 BT_DBG("conn %p", conn);
1386
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001387 if (!hcon->out && hcon->type == LE_LINK)
Ville Tervob62f3282011-02-10 22:38:50 -03001388 l2cap_le_conn_ready(conn);
1389
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001390 if (hcon->out && hcon->type == LE_LINK)
1391 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001392
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001393 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001394
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001395 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001396
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001397 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001398
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001399 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1400 l2cap_chan_unlock(chan);
1401 continue;
1402 }
1403
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001404 if (hcon->type == LE_LINK) {
1405 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001406 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001407
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001408 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001409 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001410 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001411 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001412 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001413 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001414 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001415
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001416 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001417 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001418
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001419 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001420 }
1421
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001422 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001423}
1424
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001425/* Notify sockets that we cannot guaranty reliability anymore */
1426static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1427{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001428 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001429
1430 BT_DBG("conn %p", conn);
1431
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001432 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001433
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001434 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001435 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001436 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001437 }
1438
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001439 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001440}
1441
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001442static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001443{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001444 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001445 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001446
Marcel Holtmann984947d2009-02-06 23:35:19 +01001447 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001448 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001449
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001450 l2cap_conn_start(conn);
1451}
1452
David Herrmann2c8e1412013-04-06 20:28:45 +02001453/*
1454 * l2cap_user
1455 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1456 * callback is called during registration. The ->remove callback is called
1457 * during unregistration.
1458 * An l2cap_user object can either be explicitly unregistered or when the
1459 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1460 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1461 * External modules must own a reference to the l2cap_conn object if they intend
1462 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1463 * any time if they don't.
1464 */
1465
1466int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1467{
1468 struct hci_dev *hdev = conn->hcon->hdev;
1469 int ret;
1470
1471 /* We need to check whether l2cap_conn is registered. If it is not, we
1472 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1473 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1474 * relies on the parent hci_conn object to be locked. This itself relies
1475 * on the hci_dev object to be locked. So we must lock the hci device
1476 * here, too. */
1477
1478 hci_dev_lock(hdev);
1479
1480 if (user->list.next || user->list.prev) {
1481 ret = -EINVAL;
1482 goto out_unlock;
1483 }
1484
1485 /* conn->hchan is NULL after l2cap_conn_del() was called */
1486 if (!conn->hchan) {
1487 ret = -ENODEV;
1488 goto out_unlock;
1489 }
1490
1491 ret = user->probe(conn, user);
1492 if (ret)
1493 goto out_unlock;
1494
1495 list_add(&user->list, &conn->users);
1496 ret = 0;
1497
1498out_unlock:
1499 hci_dev_unlock(hdev);
1500 return ret;
1501}
1502EXPORT_SYMBOL(l2cap_register_user);
1503
1504void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1505{
1506 struct hci_dev *hdev = conn->hcon->hdev;
1507
1508 hci_dev_lock(hdev);
1509
1510 if (!user->list.next || !user->list.prev)
1511 goto out_unlock;
1512
1513 list_del(&user->list);
1514 user->list.next = NULL;
1515 user->list.prev = NULL;
1516 user->remove(conn, user);
1517
1518out_unlock:
1519 hci_dev_unlock(hdev);
1520}
1521EXPORT_SYMBOL(l2cap_unregister_user);
1522
1523static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1524{
1525 struct l2cap_user *user;
1526
1527 while (!list_empty(&conn->users)) {
1528 user = list_first_entry(&conn->users, struct l2cap_user, list);
1529 list_del(&user->list);
1530 user->list.next = NULL;
1531 user->list.prev = NULL;
1532 user->remove(conn, user);
1533 }
1534}
1535
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001536static void l2cap_conn_del(struct hci_conn *hcon, int err)
1537{
1538 struct l2cap_conn *conn = hcon->l2cap_data;
1539 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001540
1541 if (!conn)
1542 return;
1543
1544 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1545
1546 kfree_skb(conn->rx_skb);
1547
David Herrmann2c8e1412013-04-06 20:28:45 +02001548 l2cap_unregister_all_users(conn);
1549
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001550 mutex_lock(&conn->chan_lock);
1551
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001552 /* Kill channels */
1553 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001554 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001555 l2cap_chan_lock(chan);
1556
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001557 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001558
1559 l2cap_chan_unlock(chan);
1560
Gustavo Padovan80b98022012-05-27 22:27:51 -03001561 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001562 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001563 }
1564
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001565 mutex_unlock(&conn->chan_lock);
1566
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001567 hci_chan_del(conn->hchan);
1568
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001569 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001570 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001571
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001572 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001573 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001574 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001575 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001576
1577 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001578 conn->hchan = NULL;
1579 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001580}
1581
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001582static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001583{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001584 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001585 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001586
Johan Hedbergd06cc412012-06-06 18:44:11 +08001587 BT_DBG("conn %p", conn);
1588
1589 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1590 smp_chan_destroy(conn);
1591 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1592 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001593}
1594
Claudio Takahasibaf43252013-04-11 13:55:50 -03001595static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596{
Marcel Holtmann01394182006-07-03 10:02:46 +02001597 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001598 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599
Claudio Takahasibaf43252013-04-11 13:55:50 -03001600 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601 return conn;
1602
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001603 hchan = hci_chan_create(hcon);
1604 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001607 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001608 if (!conn) {
1609 hci_chan_del(hchan);
1610 return NULL;
1611 }
1612
David Herrmann9c903e32013-04-06 20:28:44 +02001613 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614 hcon->l2cap_data = conn;
1615 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001616 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001617 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001619 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001620
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001621 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001622 case LE_LINK:
1623 if (hcon->hdev->le_mtu) {
1624 conn->mtu = hcon->hdev->le_mtu;
1625 break;
1626 }
1627 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001628 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001629 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001630 break;
1631 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001632
Linus Torvalds1da177e2005-04-16 15:20:36 -07001633 conn->src = &hcon->hdev->bdaddr;
1634 conn->dst = &hcon->dst;
1635
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001636 conn->feat_mask = 0;
1637
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001639 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001640
1641 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001642 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001644 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001645 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001646 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001647 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001648
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001649 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001650
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651 return conn;
1652}
1653
David Herrmann9c903e32013-04-06 20:28:44 +02001654static void l2cap_conn_free(struct kref *ref)
1655{
1656 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1657
1658 hci_conn_put(conn->hcon);
1659 kfree(conn);
1660}
1661
1662void l2cap_conn_get(struct l2cap_conn *conn)
1663{
1664 kref_get(&conn->ref);
1665}
1666EXPORT_SYMBOL(l2cap_conn_get);
1667
1668void l2cap_conn_put(struct l2cap_conn *conn)
1669{
1670 kref_put(&conn->ref, l2cap_conn_free);
1671}
1672EXPORT_SYMBOL(l2cap_conn_put);
1673
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675
Ido Yarivc2287682012-04-20 15:46:07 -03001676/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677 * Returns closest match.
1678 */
Ido Yarivc2287682012-04-20 15:46:07 -03001679static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1680 bdaddr_t *src,
1681 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001683 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001685 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001686
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001687 list_for_each_entry(c, &chan_list, global_l) {
1688 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001689
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001690 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691 continue;
1692
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001693 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001694 int src_match, dst_match;
1695 int src_any, dst_any;
1696
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001698 src_match = !bacmp(&bt_sk(sk)->src, src);
1699 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1700 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001701 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001702 return c;
1703 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704
1705 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001706 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1707 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1708 if ((src_match && dst_any) || (src_any && dst_match) ||
1709 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001710 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711 }
1712 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001714 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001715
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001716 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717}
1718
Andre Guedes8e9f9892012-04-24 21:02:55 -03001719int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1720 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001722 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724 struct l2cap_conn *conn;
1725 struct hci_conn *hcon;
1726 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001727 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001728 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001730 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301731 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001733 hdev = hci_get_route(dst, src);
1734 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735 return -EHOSTUNREACH;
1736
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001737 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001739 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001740
1741 /* PSM must be odd and lsb of upper byte must be 0 */
1742 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001743 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001744 err = -EINVAL;
1745 goto done;
1746 }
1747
1748 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1749 err = -EINVAL;
1750 goto done;
1751 }
1752
1753 switch (chan->mode) {
1754 case L2CAP_MODE_BASIC:
1755 break;
1756 case L2CAP_MODE_ERTM:
1757 case L2CAP_MODE_STREAMING:
1758 if (!disable_ertm)
1759 break;
1760 /* fall through */
1761 default:
1762 err = -ENOTSUPP;
1763 goto done;
1764 }
1765
Gustavo Padovan0797e012012-05-27 22:27:54 -03001766 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001767 case BT_CONNECT:
1768 case BT_CONNECT2:
1769 case BT_CONFIG:
1770 /* Already connecting */
1771 err = 0;
1772 goto done;
1773
1774 case BT_CONNECTED:
1775 /* Already connected */
1776 err = -EISCONN;
1777 goto done;
1778
1779 case BT_OPEN:
1780 case BT_BOUND:
1781 /* Can connect */
1782 break;
1783
1784 default:
1785 err = -EBADFD;
1786 goto done;
1787 }
1788
1789 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001790 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001791 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001792 release_sock(sk);
1793
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001794 chan->psm = psm;
1795 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001797 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001798
Johan Hedbergf224ca52013-04-29 19:35:36 +03001799 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001800 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001801 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001802 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001803 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001804 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001805
Ville Tervo30e76272011-02-22 16:10:53 -03001806 if (IS_ERR(hcon)) {
1807 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001809 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810
Claudio Takahasibaf43252013-04-11 13:55:50 -03001811 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001813 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001814 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815 goto done;
1816 }
1817
Johan Hedberg141d5702013-04-29 19:35:37 +03001818 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1819 hci_conn_drop(hcon);
1820 err = -EBUSY;
1821 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001822 }
1823
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824 /* Update source addr of the socket */
1825 bacpy(src, conn->src);
1826
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001827 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001828 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001829 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001830
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001831 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001832 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833
1834 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001835 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001836 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001837 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001838 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001839 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001840 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 }
1842
Ville Tervo30e76272011-02-22 16:10:53 -03001843 err = 0;
1844
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001846 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001847 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848 hci_dev_put(hdev);
1849 return err;
1850}
1851
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001852int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001853{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001854 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001855 DECLARE_WAITQUEUE(wait, current);
1856 int err = 0;
1857 int timeo = HZ/5;
1858
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001859 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001860 set_current_state(TASK_INTERRUPTIBLE);
1861 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001862 if (!timeo)
1863 timeo = HZ/5;
1864
1865 if (signal_pending(current)) {
1866 err = sock_intr_errno(timeo);
1867 break;
1868 }
1869
1870 release_sock(sk);
1871 timeo = schedule_timeout(timeo);
1872 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001873 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001874
1875 err = sock_error(sk);
1876 if (err)
1877 break;
1878 }
1879 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001880 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001881 return err;
1882}
1883
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001884static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001885{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001886 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001887 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001888
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001889 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001890
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001891 l2cap_chan_lock(chan);
1892
Mat Martineau80909e02012-05-17 20:53:50 -07001893 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001894 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001895 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001896 return;
1897 }
1898
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001899 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001900
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001901 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001902 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001903}
1904
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001905static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001906{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001907 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001908 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001909
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001910 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001911
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001912 l2cap_chan_lock(chan);
1913
Mat Martineau80909e02012-05-17 20:53:50 -07001914 if (!chan->conn) {
1915 l2cap_chan_unlock(chan);
1916 l2cap_chan_put(chan);
1917 return;
1918 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001919
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001920 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001921 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001922 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001923}
1924
Gustavo Padovand6603662012-05-21 13:58:22 -03001925static void l2cap_streaming_send(struct l2cap_chan *chan,
1926 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001927{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001928 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001929 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001930
Mat Martineau37339372012-05-17 20:53:33 -07001931 BT_DBG("chan %p, skbs %p", chan, skbs);
1932
Mat Martineaub99e13a2012-10-23 15:24:19 -07001933 if (__chan_is_moving(chan))
1934 return;
1935
Mat Martineau37339372012-05-17 20:53:33 -07001936 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1937
1938 while (!skb_queue_empty(&chan->tx_q)) {
1939
1940 skb = skb_dequeue(&chan->tx_q);
1941
1942 bt_cb(skb)->control.retries = 1;
1943 control = &bt_cb(skb)->control;
1944
1945 control->reqseq = 0;
1946 control->txseq = chan->next_tx_seq;
1947
1948 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001949
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001950 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001951 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1952 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001953 }
1954
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001955 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001956
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001957 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001958
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001959 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001960 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001961 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001962}
1963
Szymon Janc67c9e842011-07-28 16:24:33 +02001964static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001965{
1966 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001967 struct l2cap_ctrl *control;
1968 int sent = 0;
1969
1970 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001971
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001972 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001973 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001974
Mat Martineau94122bb2012-05-02 09:42:02 -07001975 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1976 return 0;
1977
Mat Martineaub99e13a2012-10-23 15:24:19 -07001978 if (__chan_is_moving(chan))
1979 return 0;
1980
Mat Martineau18a48e72012-05-17 20:53:34 -07001981 while (chan->tx_send_head &&
1982 chan->unacked_frames < chan->remote_tx_win &&
1983 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001984
Mat Martineau18a48e72012-05-17 20:53:34 -07001985 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001986
Mat Martineau18a48e72012-05-17 20:53:34 -07001987 bt_cb(skb)->control.retries = 1;
1988 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001989
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001990 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001991 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001992
Mat Martineau18a48e72012-05-17 20:53:34 -07001993 control->reqseq = chan->buffer_seq;
1994 chan->last_acked_seq = chan->buffer_seq;
1995 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001996
Mat Martineau18a48e72012-05-17 20:53:34 -07001997 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001998
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001999 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07002000 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2001 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002002 }
2003
Mat Martineau18a48e72012-05-17 20:53:34 -07002004 /* Clone after data has been modified. Data is assumed to be
2005 read-only (for locking purposes) on cloned sk_buffs.
2006 */
2007 tx_skb = skb_clone(skb, GFP_KERNEL);
2008
2009 if (!tx_skb)
2010 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002011
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002012 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002013
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002014 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002015 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002016 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002017 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002018
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002019 if (skb_queue_is_last(&chan->tx_q, skb))
2020 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002021 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002022 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002023
2024 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002025 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002026 }
2027
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002028 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2029 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002030
2031 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002032}
2033
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002034static void l2cap_ertm_resend(struct l2cap_chan *chan)
2035{
2036 struct l2cap_ctrl control;
2037 struct sk_buff *skb;
2038 struct sk_buff *tx_skb;
2039 u16 seq;
2040
2041 BT_DBG("chan %p", chan);
2042
2043 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2044 return;
2045
Mat Martineaub99e13a2012-10-23 15:24:19 -07002046 if (__chan_is_moving(chan))
2047 return;
2048
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002049 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2050 seq = l2cap_seq_list_pop(&chan->retrans_list);
2051
2052 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2053 if (!skb) {
2054 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002055 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002056 continue;
2057 }
2058
2059 bt_cb(skb)->control.retries++;
2060 control = bt_cb(skb)->control;
2061
2062 if (chan->max_tx != 0 &&
2063 bt_cb(skb)->control.retries > chan->max_tx) {
2064 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002065 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002066 l2cap_seq_list_clear(&chan->retrans_list);
2067 break;
2068 }
2069
2070 control.reqseq = chan->buffer_seq;
2071 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2072 control.final = 1;
2073 else
2074 control.final = 0;
2075
2076 if (skb_cloned(skb)) {
2077 /* Cloned sk_buffs are read-only, so we need a
2078 * writeable copy
2079 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002080 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002081 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002082 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002083 }
2084
2085 if (!tx_skb) {
2086 l2cap_seq_list_clear(&chan->retrans_list);
2087 break;
2088 }
2089
2090 /* Update skb contents */
2091 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2092 put_unaligned_le32(__pack_extended_control(&control),
2093 tx_skb->data + L2CAP_HDR_SIZE);
2094 } else {
2095 put_unaligned_le16(__pack_enhanced_control(&control),
2096 tx_skb->data + L2CAP_HDR_SIZE);
2097 }
2098
2099 if (chan->fcs == L2CAP_FCS_CRC16) {
2100 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2101 put_unaligned_le16(fcs, skb_put(tx_skb,
2102 L2CAP_FCS_SIZE));
2103 }
2104
2105 l2cap_do_send(chan, tx_skb);
2106
2107 BT_DBG("Resent txseq %d", control.txseq);
2108
2109 chan->last_acked_seq = chan->buffer_seq;
2110 }
2111}
2112
Mat Martineauf80842a2012-05-17 20:53:46 -07002113static void l2cap_retransmit(struct l2cap_chan *chan,
2114 struct l2cap_ctrl *control)
2115{
2116 BT_DBG("chan %p, control %p", chan, control);
2117
2118 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2119 l2cap_ertm_resend(chan);
2120}
2121
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002122static void l2cap_retransmit_all(struct l2cap_chan *chan,
2123 struct l2cap_ctrl *control)
2124{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002125 struct sk_buff *skb;
2126
2127 BT_DBG("chan %p, control %p", chan, control);
2128
2129 if (control->poll)
2130 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2131
2132 l2cap_seq_list_clear(&chan->retrans_list);
2133
2134 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2135 return;
2136
2137 if (chan->unacked_frames) {
2138 skb_queue_walk(&chan->tx_q, skb) {
2139 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002140 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002141 break;
2142 }
2143
2144 skb_queue_walk_from(&chan->tx_q, skb) {
2145 if (skb == chan->tx_send_head)
2146 break;
2147
2148 l2cap_seq_list_append(&chan->retrans_list,
2149 bt_cb(skb)->control.txseq);
2150 }
2151
2152 l2cap_ertm_resend(chan);
2153 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002154}
2155
Szymon Jancb17e73b2012-01-11 10:59:47 +01002156static void l2cap_send_ack(struct l2cap_chan *chan)
2157{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002158 struct l2cap_ctrl control;
2159 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2160 chan->last_acked_seq);
2161 int threshold;
2162
2163 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2164 chan, chan->last_acked_seq, chan->buffer_seq);
2165
2166 memset(&control, 0, sizeof(control));
2167 control.sframe = 1;
2168
2169 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2170 chan->rx_state == L2CAP_RX_STATE_RECV) {
2171 __clear_ack_timer(chan);
2172 control.super = L2CAP_SUPER_RNR;
2173 control.reqseq = chan->buffer_seq;
2174 l2cap_send_sframe(chan, &control);
2175 } else {
2176 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2177 l2cap_ertm_send(chan);
2178 /* If any i-frames were sent, they included an ack */
2179 if (chan->buffer_seq == chan->last_acked_seq)
2180 frames_to_ack = 0;
2181 }
2182
Mat Martineauc20f8e32012-07-10 05:47:07 -07002183 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002184 * Calculate without mul or div
2185 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002186 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002187 threshold += threshold << 1;
2188 threshold >>= 2;
2189
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002190 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002191 threshold);
2192
2193 if (frames_to_ack >= threshold) {
2194 __clear_ack_timer(chan);
2195 control.super = L2CAP_SUPER_RR;
2196 control.reqseq = chan->buffer_seq;
2197 l2cap_send_sframe(chan, &control);
2198 frames_to_ack = 0;
2199 }
2200
2201 if (frames_to_ack)
2202 __set_ack_timer(chan);
2203 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002204}
2205
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002206static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2207 struct msghdr *msg, int len,
2208 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002209{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002210 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002211 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002212 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002213
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002214 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002215 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002216
2217 sent += count;
2218 len -= count;
2219
2220 /* Continuation fragments (no L2CAP header) */
2221 frag = &skb_shinfo(skb)->frag_list;
2222 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002223 struct sk_buff *tmp;
2224
Linus Torvalds1da177e2005-04-16 15:20:36 -07002225 count = min_t(unsigned int, conn->mtu, len);
2226
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002227 tmp = chan->ops->alloc_skb(chan, count,
2228 msg->msg_flags & MSG_DONTWAIT);
2229 if (IS_ERR(tmp))
2230 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002231
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002232 *frag = tmp;
2233
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002234 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2235 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002236
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002237 (*frag)->priority = skb->priority;
2238
Linus Torvalds1da177e2005-04-16 15:20:36 -07002239 sent += count;
2240 len -= count;
2241
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002242 skb->len += (*frag)->len;
2243 skb->data_len += (*frag)->len;
2244
Linus Torvalds1da177e2005-04-16 15:20:36 -07002245 frag = &(*frag)->next;
2246 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002247
2248 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002249}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002250
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002251static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002252 struct msghdr *msg, size_t len,
2253 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002254{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002255 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002256 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002257 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002258 struct l2cap_hdr *lh;
2259
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002260 BT_DBG("chan %p len %zu priority %u", chan, len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002261
2262 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002263
2264 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002265 msg->msg_flags & MSG_DONTWAIT);
2266 if (IS_ERR(skb))
2267 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002268
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002269 skb->priority = priority;
2270
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002271 /* Create L2CAP header */
2272 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002273 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002274 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
2275 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002276
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002277 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002278 if (unlikely(err < 0)) {
2279 kfree_skb(skb);
2280 return ERR_PTR(err);
2281 }
2282 return skb;
2283}
2284
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002285static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002286 struct msghdr *msg, size_t len,
2287 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002288{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002289 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002290 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002291 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002292 struct l2cap_hdr *lh;
2293
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002294 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002295
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002296 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002297
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002298 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002299 msg->msg_flags & MSG_DONTWAIT);
2300 if (IS_ERR(skb))
2301 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002302
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002303 skb->priority = priority;
2304
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002305 /* Create L2CAP header */
2306 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002307 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002308 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002309
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002310 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002311 if (unlikely(err < 0)) {
2312 kfree_skb(skb);
2313 return ERR_PTR(err);
2314 }
2315 return skb;
2316}
2317
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002318static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002319 struct msghdr *msg, size_t len,
2320 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002321{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002322 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002323 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002324 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002325 struct l2cap_hdr *lh;
2326
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002327 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002328
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002329 if (!conn)
2330 return ERR_PTR(-ENOTCONN);
2331
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002332 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002333
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002334 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002335 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002336
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002337 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002338 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002339
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002340 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002341
2342 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002343 msg->msg_flags & MSG_DONTWAIT);
2344 if (IS_ERR(skb))
2345 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002346
2347 /* Create L2CAP header */
2348 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002349 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002350 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002351
Mat Martineau18a48e72012-05-17 20:53:34 -07002352 /* Control header is populated later */
2353 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2354 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2355 else
2356 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002357
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002358 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002359 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002360
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002361 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002362 if (unlikely(err < 0)) {
2363 kfree_skb(skb);
2364 return ERR_PTR(err);
2365 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002366
Mat Martineau18a48e72012-05-17 20:53:34 -07002367 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002368 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002369 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002370}
2371
Mat Martineau94122bb2012-05-02 09:42:02 -07002372static int l2cap_segment_sdu(struct l2cap_chan *chan,
2373 struct sk_buff_head *seg_queue,
2374 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002375{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002376 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002377 u16 sdu_len;
2378 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002379 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002380
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002381 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002382
Mat Martineau94122bb2012-05-02 09:42:02 -07002383 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2384 * so fragmented skbs are not used. The HCI layer's handling
2385 * of fragmented skbs is not compatible with ERTM's queueing.
2386 */
2387
2388 /* PDU size is derived from the HCI MTU */
2389 pdu_len = chan->conn->mtu;
2390
Mat Martineaua5495742012-10-23 15:24:21 -07002391 /* Constrain PDU size for BR/EDR connections */
2392 if (!chan->hs_hcon)
2393 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002394
2395 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002396 if (chan->fcs)
2397 pdu_len -= L2CAP_FCS_SIZE;
2398
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002399 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002400
2401 /* Remote device may have requested smaller PDUs */
2402 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2403
2404 if (len <= pdu_len) {
2405 sar = L2CAP_SAR_UNSEGMENTED;
2406 sdu_len = 0;
2407 pdu_len = len;
2408 } else {
2409 sar = L2CAP_SAR_START;
2410 sdu_len = len;
2411 pdu_len -= L2CAP_SDULEN_SIZE;
2412 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002413
2414 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002415 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002416
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002417 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002418 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002419 return PTR_ERR(skb);
2420 }
2421
Mat Martineau94122bb2012-05-02 09:42:02 -07002422 bt_cb(skb)->control.sar = sar;
2423 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002424
Mat Martineau94122bb2012-05-02 09:42:02 -07002425 len -= pdu_len;
2426 if (sdu_len) {
2427 sdu_len = 0;
2428 pdu_len += L2CAP_SDULEN_SIZE;
2429 }
2430
2431 if (len <= pdu_len) {
2432 sar = L2CAP_SAR_END;
2433 pdu_len = len;
2434 } else {
2435 sar = L2CAP_SAR_CONTINUE;
2436 }
2437 }
2438
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002439 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002440}
2441
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002442int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002443 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002444{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002445 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002446 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002447 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002448
2449 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002450 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002451 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002452 if (IS_ERR(skb))
2453 return PTR_ERR(skb);
2454
2455 l2cap_do_send(chan, skb);
2456 return len;
2457 }
2458
2459 switch (chan->mode) {
2460 case L2CAP_MODE_BASIC:
2461 /* Check outgoing MTU */
2462 if (len > chan->omtu)
2463 return -EMSGSIZE;
2464
2465 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002466 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002467 if (IS_ERR(skb))
2468 return PTR_ERR(skb);
2469
2470 l2cap_do_send(chan, skb);
2471 err = len;
2472 break;
2473
2474 case L2CAP_MODE_ERTM:
2475 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002476 /* Check outgoing MTU */
2477 if (len > chan->omtu) {
2478 err = -EMSGSIZE;
2479 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002480 }
2481
Mat Martineau94122bb2012-05-02 09:42:02 -07002482 __skb_queue_head_init(&seg_queue);
2483
2484 /* Do segmentation before calling in to the state machine,
2485 * since it's possible to block while waiting for memory
2486 * allocation.
2487 */
2488 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2489
2490 /* The channel could have been closed while segmenting,
2491 * check that it is still connected.
2492 */
2493 if (chan->state != BT_CONNECTED) {
2494 __skb_queue_purge(&seg_queue);
2495 err = -ENOTCONN;
2496 }
2497
2498 if (err)
2499 break;
2500
Mat Martineau37339372012-05-17 20:53:33 -07002501 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002502 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002503 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002504 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002505
Gustavo Padovand6603662012-05-21 13:58:22 -03002506 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002507
Mat Martineau94122bb2012-05-02 09:42:02 -07002508 /* If the skbs were not queued for sending, they'll still be in
2509 * seg_queue and need to be purged.
2510 */
2511 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002512 break;
2513
2514 default:
2515 BT_DBG("bad state %1.1x", chan->mode);
2516 err = -EBADFD;
2517 }
2518
2519 return err;
2520}
2521
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002522static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2523{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002524 struct l2cap_ctrl control;
2525 u16 seq;
2526
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002527 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002528
2529 memset(&control, 0, sizeof(control));
2530 control.sframe = 1;
2531 control.super = L2CAP_SUPER_SREJ;
2532
2533 for (seq = chan->expected_tx_seq; seq != txseq;
2534 seq = __next_seq(chan, seq)) {
2535 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2536 control.reqseq = seq;
2537 l2cap_send_sframe(chan, &control);
2538 l2cap_seq_list_append(&chan->srej_list, seq);
2539 }
2540 }
2541
2542 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002543}
2544
2545static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2546{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002547 struct l2cap_ctrl control;
2548
2549 BT_DBG("chan %p", chan);
2550
2551 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2552 return;
2553
2554 memset(&control, 0, sizeof(control));
2555 control.sframe = 1;
2556 control.super = L2CAP_SUPER_SREJ;
2557 control.reqseq = chan->srej_list.tail;
2558 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002559}
2560
2561static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2562{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002563 struct l2cap_ctrl control;
2564 u16 initial_head;
2565 u16 seq;
2566
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002567 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002568
2569 memset(&control, 0, sizeof(control));
2570 control.sframe = 1;
2571 control.super = L2CAP_SUPER_SREJ;
2572
2573 /* Capture initial list head to allow only one pass through the list. */
2574 initial_head = chan->srej_list.head;
2575
2576 do {
2577 seq = l2cap_seq_list_pop(&chan->srej_list);
2578 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2579 break;
2580
2581 control.reqseq = seq;
2582 l2cap_send_sframe(chan, &control);
2583 l2cap_seq_list_append(&chan->srej_list, seq);
2584 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002585}
2586
Mat Martineau608bcc62012-05-17 20:53:32 -07002587static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2588{
2589 struct sk_buff *acked_skb;
2590 u16 ackseq;
2591
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002592 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002593
2594 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2595 return;
2596
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002597 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002598 chan->expected_ack_seq, chan->unacked_frames);
2599
2600 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2601 ackseq = __next_seq(chan, ackseq)) {
2602
2603 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2604 if (acked_skb) {
2605 skb_unlink(acked_skb, &chan->tx_q);
2606 kfree_skb(acked_skb);
2607 chan->unacked_frames--;
2608 }
2609 }
2610
2611 chan->expected_ack_seq = reqseq;
2612
2613 if (chan->unacked_frames == 0)
2614 __clear_retrans_timer(chan);
2615
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002616 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002617}
2618
2619static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2620{
2621 BT_DBG("chan %p", chan);
2622
2623 chan->expected_tx_seq = chan->buffer_seq;
2624 l2cap_seq_list_clear(&chan->srej_list);
2625 skb_queue_purge(&chan->srej_q);
2626 chan->rx_state = L2CAP_RX_STATE_RECV;
2627}
2628
Gustavo Padovand6603662012-05-21 13:58:22 -03002629static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2630 struct l2cap_ctrl *control,
2631 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002632{
Mat Martineau608bcc62012-05-17 20:53:32 -07002633 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2634 event);
2635
2636 switch (event) {
2637 case L2CAP_EV_DATA_REQUEST:
2638 if (chan->tx_send_head == NULL)
2639 chan->tx_send_head = skb_peek(skbs);
2640
2641 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2642 l2cap_ertm_send(chan);
2643 break;
2644 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2645 BT_DBG("Enter LOCAL_BUSY");
2646 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2647
2648 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2649 /* The SREJ_SENT state must be aborted if we are to
2650 * enter the LOCAL_BUSY state.
2651 */
2652 l2cap_abort_rx_srej_sent(chan);
2653 }
2654
2655 l2cap_send_ack(chan);
2656
2657 break;
2658 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2659 BT_DBG("Exit LOCAL_BUSY");
2660 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2661
2662 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2663 struct l2cap_ctrl local_control;
2664
2665 memset(&local_control, 0, sizeof(local_control));
2666 local_control.sframe = 1;
2667 local_control.super = L2CAP_SUPER_RR;
2668 local_control.poll = 1;
2669 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002670 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002671
2672 chan->retry_count = 1;
2673 __set_monitor_timer(chan);
2674 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2675 }
2676 break;
2677 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2678 l2cap_process_reqseq(chan, control->reqseq);
2679 break;
2680 case L2CAP_EV_EXPLICIT_POLL:
2681 l2cap_send_rr_or_rnr(chan, 1);
2682 chan->retry_count = 1;
2683 __set_monitor_timer(chan);
2684 __clear_ack_timer(chan);
2685 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2686 break;
2687 case L2CAP_EV_RETRANS_TO:
2688 l2cap_send_rr_or_rnr(chan, 1);
2689 chan->retry_count = 1;
2690 __set_monitor_timer(chan);
2691 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2692 break;
2693 case L2CAP_EV_RECV_FBIT:
2694 /* Nothing to process */
2695 break;
2696 default:
2697 break;
2698 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002699}
2700
Gustavo Padovand6603662012-05-21 13:58:22 -03002701static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2702 struct l2cap_ctrl *control,
2703 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002704{
Mat Martineau608bcc62012-05-17 20:53:32 -07002705 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2706 event);
2707
2708 switch (event) {
2709 case L2CAP_EV_DATA_REQUEST:
2710 if (chan->tx_send_head == NULL)
2711 chan->tx_send_head = skb_peek(skbs);
2712 /* Queue data, but don't send. */
2713 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2714 break;
2715 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2716 BT_DBG("Enter LOCAL_BUSY");
2717 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2718
2719 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2720 /* The SREJ_SENT state must be aborted if we are to
2721 * enter the LOCAL_BUSY state.
2722 */
2723 l2cap_abort_rx_srej_sent(chan);
2724 }
2725
2726 l2cap_send_ack(chan);
2727
2728 break;
2729 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2730 BT_DBG("Exit LOCAL_BUSY");
2731 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2732
2733 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2734 struct l2cap_ctrl local_control;
2735 memset(&local_control, 0, sizeof(local_control));
2736 local_control.sframe = 1;
2737 local_control.super = L2CAP_SUPER_RR;
2738 local_control.poll = 1;
2739 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002740 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002741
2742 chan->retry_count = 1;
2743 __set_monitor_timer(chan);
2744 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2745 }
2746 break;
2747 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2748 l2cap_process_reqseq(chan, control->reqseq);
2749
2750 /* Fall through */
2751
2752 case L2CAP_EV_RECV_FBIT:
2753 if (control && control->final) {
2754 __clear_monitor_timer(chan);
2755 if (chan->unacked_frames > 0)
2756 __set_retrans_timer(chan);
2757 chan->retry_count = 0;
2758 chan->tx_state = L2CAP_TX_STATE_XMIT;
2759 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2760 }
2761 break;
2762 case L2CAP_EV_EXPLICIT_POLL:
2763 /* Ignore */
2764 break;
2765 case L2CAP_EV_MONITOR_TO:
2766 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2767 l2cap_send_rr_or_rnr(chan, 1);
2768 __set_monitor_timer(chan);
2769 chan->retry_count++;
2770 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002771 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002772 }
2773 break;
2774 default:
2775 break;
2776 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002777}
2778
Gustavo Padovand6603662012-05-21 13:58:22 -03002779static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2780 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002781{
Mat Martineau608bcc62012-05-17 20:53:32 -07002782 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2783 chan, control, skbs, event, chan->tx_state);
2784
2785 switch (chan->tx_state) {
2786 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002787 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002788 break;
2789 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002790 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002791 break;
2792 default:
2793 /* Ignore event */
2794 break;
2795 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002796}
2797
Mat Martineau4b51dae92012-05-17 20:53:37 -07002798static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2799 struct l2cap_ctrl *control)
2800{
2801 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002802 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002803}
2804
Mat Martineauf80842a2012-05-17 20:53:46 -07002805static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2806 struct l2cap_ctrl *control)
2807{
2808 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002809 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002810}
2811
Linus Torvalds1da177e2005-04-16 15:20:36 -07002812/* Copy frame to all raw sockets on that connection */
2813static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2814{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002815 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002816 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817
2818 BT_DBG("conn %p", conn);
2819
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002820 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002821
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002822 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002823 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002824 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002825 continue;
2826
2827 /* Don't send frame to the socket it came from */
2828 if (skb->sk == sk)
2829 continue;
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002830 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002831 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002832 continue;
2833
Gustavo Padovan80b98022012-05-27 22:27:51 -03002834 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002835 kfree_skb(nskb);
2836 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002837
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002838 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002839}
2840
2841/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002842static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2843 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002844{
2845 struct sk_buff *skb, **frag;
2846 struct l2cap_cmd_hdr *cmd;
2847 struct l2cap_hdr *lh;
2848 int len, count;
2849
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002850 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2851 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002852
Anderson Lizardo300b9622013-06-02 16:30:40 -04002853 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2854 return NULL;
2855
Linus Torvalds1da177e2005-04-16 15:20:36 -07002856 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2857 count = min_t(unsigned int, conn->mtu, len);
2858
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002859 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002860 if (!skb)
2861 return NULL;
2862
2863 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002864 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002865
2866 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002867 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002868 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002869 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002870
2871 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2872 cmd->code = code;
2873 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002874 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002875
2876 if (dlen) {
2877 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2878 memcpy(skb_put(skb, count), data, count);
2879 data += count;
2880 }
2881
2882 len -= skb->len;
2883
2884 /* Continuation fragments (no L2CAP header) */
2885 frag = &skb_shinfo(skb)->frag_list;
2886 while (len) {
2887 count = min_t(unsigned int, conn->mtu, len);
2888
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002889 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002890 if (!*frag)
2891 goto fail;
2892
2893 memcpy(skb_put(*frag, count), data, count);
2894
2895 len -= count;
2896 data += count;
2897
2898 frag = &(*frag)->next;
2899 }
2900
2901 return skb;
2902
2903fail:
2904 kfree_skb(skb);
2905 return NULL;
2906}
2907
Gustavo Padovan2d792812012-10-06 10:07:01 +01002908static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2909 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002910{
2911 struct l2cap_conf_opt *opt = *ptr;
2912 int len;
2913
2914 len = L2CAP_CONF_OPT_SIZE + opt->len;
2915 *ptr += len;
2916
2917 *type = opt->type;
2918 *olen = opt->len;
2919
2920 switch (opt->len) {
2921 case 1:
2922 *val = *((u8 *) opt->val);
2923 break;
2924
2925 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002926 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927 break;
2928
2929 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002930 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002931 break;
2932
2933 default:
2934 *val = (unsigned long) opt->val;
2935 break;
2936 }
2937
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002938 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002939 return len;
2940}
2941
Linus Torvalds1da177e2005-04-16 15:20:36 -07002942static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2943{
2944 struct l2cap_conf_opt *opt = *ptr;
2945
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002946 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002947
2948 opt->type = type;
2949 opt->len = len;
2950
2951 switch (len) {
2952 case 1:
2953 *((u8 *) opt->val) = val;
2954 break;
2955
2956 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002957 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002958 break;
2959
2960 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002961 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002962 break;
2963
2964 default:
2965 memcpy(opt->val, (void *) val, len);
2966 break;
2967 }
2968
2969 *ptr += L2CAP_CONF_OPT_SIZE + len;
2970}
2971
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002972static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2973{
2974 struct l2cap_conf_efs efs;
2975
Szymon Janc1ec918c2011-11-16 09:32:21 +01002976 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002977 case L2CAP_MODE_ERTM:
2978 efs.id = chan->local_id;
2979 efs.stype = chan->local_stype;
2980 efs.msdu = cpu_to_le16(chan->local_msdu);
2981 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002982 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002983 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002984 break;
2985
2986 case L2CAP_MODE_STREAMING:
2987 efs.id = 1;
2988 efs.stype = L2CAP_SERV_BESTEFFORT;
2989 efs.msdu = cpu_to_le16(chan->local_msdu);
2990 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2991 efs.acc_lat = 0;
2992 efs.flush_to = 0;
2993 break;
2994
2995 default:
2996 return;
2997 }
2998
2999 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003000 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003001}
3002
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003003static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003004{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003005 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003006 ack_timer.work);
3007 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003008
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003009 BT_DBG("chan %p", chan);
3010
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003011 l2cap_chan_lock(chan);
3012
Mat Martineau03625202012-05-17 20:53:51 -07003013 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3014 chan->last_acked_seq);
3015
3016 if (frames_to_ack)
3017 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003018
3019 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003020 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003021}
3022
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003023int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003024{
Mat Martineau3c588192012-04-11 10:48:42 -07003025 int err;
3026
Mat Martineau105bdf92012-04-27 16:50:48 -07003027 chan->next_tx_seq = 0;
3028 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003029 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003030 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003031 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003032 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003033 chan->last_acked_seq = 0;
3034 chan->sdu = NULL;
3035 chan->sdu_last_frag = NULL;
3036 chan->sdu_len = 0;
3037
Mat Martineaud34c34f2012-05-14 14:49:27 -07003038 skb_queue_head_init(&chan->tx_q);
3039
Mat Martineau08333282012-10-23 15:24:06 -07003040 chan->local_amp_id = 0;
3041 chan->move_id = 0;
3042 chan->move_state = L2CAP_MOVE_STABLE;
3043 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3044
Mat Martineau105bdf92012-04-27 16:50:48 -07003045 if (chan->mode != L2CAP_MODE_ERTM)
3046 return 0;
3047
3048 chan->rx_state = L2CAP_RX_STATE_RECV;
3049 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003050
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003051 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3052 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3053 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003054
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003055 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003056
Mat Martineau3c588192012-04-11 10:48:42 -07003057 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3058 if (err < 0)
3059 return err;
3060
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003061 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3062 if (err < 0)
3063 l2cap_seq_list_free(&chan->srej_list);
3064
3065 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003066}
3067
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003068static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3069{
3070 switch (mode) {
3071 case L2CAP_MODE_STREAMING:
3072 case L2CAP_MODE_ERTM:
3073 if (l2cap_mode_supported(mode, remote_feat_mask))
3074 return mode;
3075 /* fall through */
3076 default:
3077 return L2CAP_MODE_BASIC;
3078 }
3079}
3080
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003081static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
3082{
3083 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
3084}
3085
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003086static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
3087{
3088 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
3089}
3090
Mat Martineau36c86c82012-10-23 15:24:20 -07003091static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3092 struct l2cap_conf_rfc *rfc)
3093{
3094 if (chan->local_amp_id && chan->hs_hcon) {
3095 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3096
3097 /* Class 1 devices have must have ERTM timeouts
3098 * exceeding the Link Supervision Timeout. The
3099 * default Link Supervision Timeout for AMP
3100 * controllers is 10 seconds.
3101 *
3102 * Class 1 devices use 0xffffffff for their
3103 * best-effort flush timeout, so the clamping logic
3104 * will result in a timeout that meets the above
3105 * requirement. ERTM timeouts are 16-bit values, so
3106 * the maximum timeout is 65.535 seconds.
3107 */
3108
3109 /* Convert timeout to milliseconds and round */
3110 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3111
3112 /* This is the recommended formula for class 2 devices
3113 * that start ERTM timers when packets are sent to the
3114 * controller.
3115 */
3116 ertm_to = 3 * ertm_to + 500;
3117
3118 if (ertm_to > 0xffff)
3119 ertm_to = 0xffff;
3120
3121 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3122 rfc->monitor_timeout = rfc->retrans_timeout;
3123 } else {
3124 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3125 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3126 }
3127}
3128
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003129static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3130{
3131 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003132 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003133 /* use extended control field */
3134 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003135 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3136 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003137 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003138 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003139 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3140 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003141 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003142}
3143
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003144static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003145{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003146 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003147 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003148 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003149 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003150
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003151 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003152
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003153 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003154 goto done;
3155
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003156 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003157 case L2CAP_MODE_STREAMING:
3158 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003159 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003160 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003161
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003162 if (__l2cap_efs_supported(chan))
3163 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3164
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003165 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003166 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003167 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003168 break;
3169 }
3170
3171done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003172 if (chan->imtu != L2CAP_DEFAULT_MTU)
3173 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003174
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003175 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003176 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003177 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003178 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003179 break;
3180
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003181 rfc.mode = L2CAP_MODE_BASIC;
3182 rfc.txwin_size = 0;
3183 rfc.max_transmit = 0;
3184 rfc.retrans_timeout = 0;
3185 rfc.monitor_timeout = 0;
3186 rfc.max_pdu_size = 0;
3187
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003188 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003189 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003190 break;
3191
3192 case L2CAP_MODE_ERTM:
3193 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003194 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003195
3196 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003197
3198 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003199 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3200 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003201 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003202
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003203 l2cap_txwin_setup(chan);
3204
3205 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003206 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003207
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003208 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003209 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003210
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003211 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3212 l2cap_add_opt_efs(&ptr, chan);
3213
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003214 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3215 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003216 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003217
3218 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3219 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003220 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003221 chan->fcs = L2CAP_FCS_NONE;
3222 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3223 chan->fcs);
3224 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003225 break;
3226
3227 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003228 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003229 rfc.mode = L2CAP_MODE_STREAMING;
3230 rfc.txwin_size = 0;
3231 rfc.max_transmit = 0;
3232 rfc.retrans_timeout = 0;
3233 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003234
3235 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003236 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3237 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003238 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003239
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003240 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003241 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003242
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003243 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3244 l2cap_add_opt_efs(&ptr, chan);
3245
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003246 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3247 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003248 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003249 chan->fcs = L2CAP_FCS_NONE;
3250 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3251 chan->fcs);
3252 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003253 break;
3254 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003255
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003256 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003257 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003258
3259 return ptr - data;
3260}
3261
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003262static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003263{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003264 struct l2cap_conf_rsp *rsp = data;
3265 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003266 void *req = chan->conf_req;
3267 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003268 int type, hint, olen;
3269 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003270 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003271 struct l2cap_conf_efs efs;
3272 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003273 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003274 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003275 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003276
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003277 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003278
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003279 while (len >= L2CAP_CONF_OPT_SIZE) {
3280 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003281
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003282 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003283 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003284
3285 switch (type) {
3286 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003287 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003288 break;
3289
3290 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003291 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003292 break;
3293
3294 case L2CAP_CONF_QOS:
3295 break;
3296
Marcel Holtmann6464f352007-10-20 13:39:51 +02003297 case L2CAP_CONF_RFC:
3298 if (olen == sizeof(rfc))
3299 memcpy(&rfc, (void *) val, olen);
3300 break;
3301
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003302 case L2CAP_CONF_FCS:
3303 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003304 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003305 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003306
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003307 case L2CAP_CONF_EFS:
3308 remote_efs = 1;
3309 if (olen == sizeof(efs))
3310 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003311 break;
3312
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003313 case L2CAP_CONF_EWS:
3314 if (!enable_hs)
3315 return -ECONNREFUSED;
3316
3317 set_bit(FLAG_EXT_CTRL, &chan->flags);
3318 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003319 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003320 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003321 break;
3322
3323 default:
3324 if (hint)
3325 break;
3326
3327 result = L2CAP_CONF_UNKNOWN;
3328 *((u8 *) ptr++) = type;
3329 break;
3330 }
3331 }
3332
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003333 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003334 goto done;
3335
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003336 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003337 case L2CAP_MODE_STREAMING:
3338 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003339 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003340 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003341 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003342 break;
3343 }
3344
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003345 if (remote_efs) {
3346 if (__l2cap_efs_supported(chan))
3347 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3348 else
3349 return -ECONNREFUSED;
3350 }
3351
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003352 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003353 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003354
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003355 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003356 }
3357
3358done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003359 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003360 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003361 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003362
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003363 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003364 return -ECONNREFUSED;
3365
Gustavo Padovan2d792812012-10-06 10:07:01 +01003366 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3367 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003368 }
3369
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003370 if (result == L2CAP_CONF_SUCCESS) {
3371 /* Configure output options and let the other side know
3372 * which ones we don't like. */
3373
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003374 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3375 result = L2CAP_CONF_UNACCEPT;
3376 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003377 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003378 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003379 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003380 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003381
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003382 if (remote_efs) {
3383 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003384 efs.stype != L2CAP_SERV_NOTRAFIC &&
3385 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003386
3387 result = L2CAP_CONF_UNACCEPT;
3388
3389 if (chan->num_conf_req >= 1)
3390 return -ECONNREFUSED;
3391
3392 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003393 sizeof(efs),
3394 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003395 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003396 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003397 result = L2CAP_CONF_PENDING;
3398 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003399 }
3400 }
3401
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003402 switch (rfc.mode) {
3403 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003404 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003405 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003406 break;
3407
3408 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003409 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3410 chan->remote_tx_win = rfc.txwin_size;
3411 else
3412 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3413
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003414 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003415
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003416 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003417 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3418 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003419 rfc.max_pdu_size = cpu_to_le16(size);
3420 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003421
Mat Martineau36c86c82012-10-23 15:24:20 -07003422 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003423
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003424 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003425
3426 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003427 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003428
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003429 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3430 chan->remote_id = efs.id;
3431 chan->remote_stype = efs.stype;
3432 chan->remote_msdu = le16_to_cpu(efs.msdu);
3433 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003434 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003435 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003436 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003437 chan->remote_sdu_itime =
3438 le32_to_cpu(efs.sdu_itime);
3439 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003440 sizeof(efs),
3441 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003442 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003443 break;
3444
3445 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003446 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003447 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3448 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003449 rfc.max_pdu_size = cpu_to_le16(size);
3450 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003451
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003452 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003453
Gustavo Padovan2d792812012-10-06 10:07:01 +01003454 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3455 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003456
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003457 break;
3458
3459 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003460 result = L2CAP_CONF_UNACCEPT;
3461
3462 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003463 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003464 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003465
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003466 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003467 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003468 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003469 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003470 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003471 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003472
3473 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003474}
3475
Gustavo Padovan2d792812012-10-06 10:07:01 +01003476static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3477 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003478{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003479 struct l2cap_conf_req *req = data;
3480 void *ptr = req->data;
3481 int type, olen;
3482 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003483 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003484 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003485
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003486 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003487
3488 while (len >= L2CAP_CONF_OPT_SIZE) {
3489 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3490
3491 switch (type) {
3492 case L2CAP_CONF_MTU:
3493 if (val < L2CAP_DEFAULT_MIN_MTU) {
3494 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003495 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003496 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003497 chan->imtu = val;
3498 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003499 break;
3500
3501 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003502 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003503 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003504 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003505 break;
3506
3507 case L2CAP_CONF_RFC:
3508 if (olen == sizeof(rfc))
3509 memcpy(&rfc, (void *)val, olen);
3510
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003511 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003512 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003513 return -ECONNREFUSED;
3514
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003515 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003516
3517 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003518 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003519 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003520
3521 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003522 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003523 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003524 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003525 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003526
3527 case L2CAP_CONF_EFS:
3528 if (olen == sizeof(efs))
3529 memcpy(&efs, (void *)val, olen);
3530
3531 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003532 efs.stype != L2CAP_SERV_NOTRAFIC &&
3533 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003534 return -ECONNREFUSED;
3535
Gustavo Padovan2d792812012-10-06 10:07:01 +01003536 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3537 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003538 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003539
3540 case L2CAP_CONF_FCS:
3541 if (*result == L2CAP_CONF_PENDING)
3542 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003543 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003544 &chan->conf_state);
3545 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003546 }
3547 }
3548
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003549 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003550 return -ECONNREFUSED;
3551
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003552 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003553
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003554 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003555 switch (rfc.mode) {
3556 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003557 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3558 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3559 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003560 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3561 chan->ack_win = min_t(u16, chan->ack_win,
3562 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003563
3564 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3565 chan->local_msdu = le16_to_cpu(efs.msdu);
3566 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003567 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003568 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3569 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003570 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003571 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003572 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003573
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003574 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003575 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003576 }
3577 }
3578
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003579 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003580 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003581
3582 return ptr - data;
3583}
3584
Gustavo Padovan2d792812012-10-06 10:07:01 +01003585static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3586 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003587{
3588 struct l2cap_conf_rsp *rsp = data;
3589 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003590
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003591 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003592
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003593 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003594 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003595 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003596
3597 return ptr - data;
3598}
3599
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003600void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003601{
3602 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003603 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003604 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003605 u8 rsp_code;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003606
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003607 rsp.scid = cpu_to_le16(chan->dcid);
3608 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003609 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3610 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003611
3612 if (chan->hs_hcon)
3613 rsp_code = L2CAP_CREATE_CHAN_RSP;
3614 else
3615 rsp_code = L2CAP_CONN_RSP;
3616
3617 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3618
3619 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003620
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003621 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003622 return;
3623
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003624 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003625 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003626 chan->num_conf_req++;
3627}
3628
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003629static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003630{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003631 int type, olen;
3632 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003633 /* Use sane default values in case a misbehaving remote device
3634 * did not send an RFC or extended window size option.
3635 */
3636 u16 txwin_ext = chan->ack_win;
3637 struct l2cap_conf_rfc rfc = {
3638 .mode = chan->mode,
3639 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3640 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3641 .max_pdu_size = cpu_to_le16(chan->imtu),
3642 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3643 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003644
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003645 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003646
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003647 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003648 return;
3649
3650 while (len >= L2CAP_CONF_OPT_SIZE) {
3651 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3652
Mat Martineauc20f8e32012-07-10 05:47:07 -07003653 switch (type) {
3654 case L2CAP_CONF_RFC:
3655 if (olen == sizeof(rfc))
3656 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003657 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003658 case L2CAP_CONF_EWS:
3659 txwin_ext = val;
3660 break;
3661 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003662 }
3663
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003664 switch (rfc.mode) {
3665 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003666 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3667 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003668 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3669 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3670 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3671 else
3672 chan->ack_win = min_t(u16, chan->ack_win,
3673 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003674 break;
3675 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003676 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003677 }
3678}
3679
Gustavo Padovan2d792812012-10-06 10:07:01 +01003680static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003681 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3682 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003683{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003684 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003685
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003686 if (cmd_len < sizeof(*rej))
3687 return -EPROTO;
3688
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003689 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003690 return 0;
3691
3692 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003693 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003694 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003695
3696 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003697 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003698
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003699 l2cap_conn_start(conn);
3700 }
3701
3702 return 0;
3703}
3704
Mat Martineau17009152012-10-23 15:24:07 -07003705static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3706 struct l2cap_cmd_hdr *cmd,
3707 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003708{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003709 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3710 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003711 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003712 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003713 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003714
3715 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003716 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003717
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003718 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003719
3720 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003721 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003722 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003723 result = L2CAP_CR_BAD_PSM;
3724 goto sendresp;
3725 }
3726
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003727 parent = pchan->sk;
3728
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003729 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003730 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003731
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003732 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003733 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003734 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003735 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003736 result = L2CAP_CR_SEC_BLOCK;
3737 goto response;
3738 }
3739
Linus Torvalds1da177e2005-04-16 15:20:36 -07003740 result = L2CAP_CR_NO_MEM;
3741
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003742 /* Check if we already have channel with that dcid */
3743 if (__l2cap_get_chan_by_dcid(conn, scid))
3744 goto response;
3745
Gustavo Padovan80b98022012-05-27 22:27:51 -03003746 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003747 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003748 goto response;
3749
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003750 sk = chan->sk;
3751
Linus Torvalds1da177e2005-04-16 15:20:36 -07003752 hci_conn_hold(conn->hcon);
3753
Linus Torvalds1da177e2005-04-16 15:20:36 -07003754 bacpy(&bt_sk(sk)->src, conn->src);
3755 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003756 chan->psm = psm;
3757 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003758 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003759
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003760 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003761
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003762 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003763
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003764 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003765
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003766 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003767
Marcel Holtmann984947d2009-02-06 23:35:19 +01003768 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003769 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003770 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003771 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003772 result = L2CAP_CR_PEND;
3773 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003774 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003775 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003776 /* Force pending result for AMP controllers.
3777 * The connection will succeed after the
3778 * physical link is up.
3779 */
3780 if (amp_id) {
3781 __l2cap_state_change(chan, BT_CONNECT2);
3782 result = L2CAP_CR_PEND;
3783 } else {
3784 __l2cap_state_change(chan, BT_CONFIG);
3785 result = L2CAP_CR_SUCCESS;
3786 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003787 status = L2CAP_CS_NO_INFO;
3788 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003789 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003790 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003791 result = L2CAP_CR_PEND;
3792 status = L2CAP_CS_AUTHEN_PEND;
3793 }
3794 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003795 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003796 result = L2CAP_CR_PEND;
3797 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003798 }
3799
Linus Torvalds1da177e2005-04-16 15:20:36 -07003800response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003801 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003802 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003803
3804sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003805 rsp.scid = cpu_to_le16(scid);
3806 rsp.dcid = cpu_to_le16(dcid);
3807 rsp.result = cpu_to_le16(result);
3808 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003809 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003810
3811 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3812 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003813 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003814
3815 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3816 conn->info_ident = l2cap_get_ident(conn);
3817
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003818 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003819
Gustavo Padovan2d792812012-10-06 10:07:01 +01003820 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3821 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003822 }
3823
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003824 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003825 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003826 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003827 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003828 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003829 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003830 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003831 }
Mat Martineau17009152012-10-23 15:24:07 -07003832
3833 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003834}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003835
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003836static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003837 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003838{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303839 struct hci_dev *hdev = conn->hcon->hdev;
3840 struct hci_conn *hcon = conn->hcon;
3841
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003842 if (cmd_len < sizeof(struct l2cap_conn_req))
3843 return -EPROTO;
3844
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303845 hci_dev_lock(hdev);
3846 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3847 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3848 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3849 hcon->dst_type, 0, NULL, 0,
3850 hcon->dev_class);
3851 hci_dev_unlock(hdev);
3852
Gustavo Padovan300229f2012-10-12 19:40:40 +08003853 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003854 return 0;
3855}
3856
Mat Martineau5909cf32012-10-23 15:24:08 -07003857static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003858 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3859 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003860{
3861 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3862 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003863 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003864 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003865 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003866
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003867 if (cmd_len < sizeof(*rsp))
3868 return -EPROTO;
3869
Linus Torvalds1da177e2005-04-16 15:20:36 -07003870 scid = __le16_to_cpu(rsp->scid);
3871 dcid = __le16_to_cpu(rsp->dcid);
3872 result = __le16_to_cpu(rsp->result);
3873 status = __le16_to_cpu(rsp->status);
3874
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003875 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 +01003876 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003877
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003878 mutex_lock(&conn->chan_lock);
3879
Linus Torvalds1da177e2005-04-16 15:20:36 -07003880 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003881 chan = __l2cap_get_chan_by_scid(conn, scid);
3882 if (!chan) {
3883 err = -EFAULT;
3884 goto unlock;
3885 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003886 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003887 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3888 if (!chan) {
3889 err = -EFAULT;
3890 goto unlock;
3891 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003892 }
3893
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003894 err = 0;
3895
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003896 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003897
Linus Torvalds1da177e2005-04-16 15:20:36 -07003898 switch (result) {
3899 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003900 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003901 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003902 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003903 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003904
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003905 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003906 break;
3907
Linus Torvalds1da177e2005-04-16 15:20:36 -07003908 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003909 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003910 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003911 break;
3912
3913 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003914 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003915 break;
3916
3917 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003918 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003919 break;
3920 }
3921
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003922 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003923
3924unlock:
3925 mutex_unlock(&conn->chan_lock);
3926
3927 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003928}
3929
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003930static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003931{
3932 /* FCS is enabled only in ERTM or streaming mode, if one or both
3933 * sides request it.
3934 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003935 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003936 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003937 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003938 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003939}
3940
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003941static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3942 u8 ident, u16 flags)
3943{
3944 struct l2cap_conn *conn = chan->conn;
3945
3946 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3947 flags);
3948
3949 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3950 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3951
3952 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
3953 l2cap_build_conf_rsp(chan, data,
3954 L2CAP_CONF_SUCCESS, flags), data);
3955}
3956
Gustavo Padovan2d792812012-10-06 10:07:01 +01003957static inline int l2cap_config_req(struct l2cap_conn *conn,
3958 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3959 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003960{
3961 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3962 u16 dcid, flags;
3963 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003964 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003965 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003966
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003967 if (cmd_len < sizeof(*req))
3968 return -EPROTO;
3969
Linus Torvalds1da177e2005-04-16 15:20:36 -07003970 dcid = __le16_to_cpu(req->dcid);
3971 flags = __le16_to_cpu(req->flags);
3972
3973 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3974
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003975 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003976 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003977 return -ENOENT;
3978
David S. Miller033b1142011-07-21 13:38:42 -07003979 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003980 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003981
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003982 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003983 rej.scid = cpu_to_le16(chan->scid);
3984 rej.dcid = cpu_to_le16(chan->dcid);
3985
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003986 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003987 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003988 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003989 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003990
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003991 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003992 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003993 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003994 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003995 l2cap_build_conf_rsp(chan, rsp,
3996 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003997 goto unlock;
3998 }
3999
4000 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004001 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4002 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004003
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004004 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004005 /* Incomplete config. Send empty response. */
4006 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004007 l2cap_build_conf_rsp(chan, rsp,
4008 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004009 goto unlock;
4010 }
4011
4012 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004013 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004014 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004015 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004016 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004017 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004018
Mat Martineau1500109b2012-10-23 15:24:15 -07004019 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004020 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004021 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004022
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004023 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004024 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004025
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004026 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004027 goto unlock;
4028
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004029 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004030 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004031
Mat Martineau105bdf92012-04-27 16:50:48 -07004032 if (chan->mode == L2CAP_MODE_ERTM ||
4033 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004034 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004035
Mat Martineau3c588192012-04-11 10:48:42 -07004036 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004037 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004038 else
4039 l2cap_chan_ready(chan);
4040
Marcel Holtmann876d9482007-10-20 13:35:42 +02004041 goto unlock;
4042 }
4043
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004044 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004045 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004046 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004047 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004048 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004049 }
4050
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004051 /* Got Conf Rsp PENDING from remote side and asume we sent
4052 Conf Rsp PENDING in the code above */
4053 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004054 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004055
4056 /* check compatibility */
4057
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004058 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004059 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004060 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4061 else
4062 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004063 }
4064
Linus Torvalds1da177e2005-04-16 15:20:36 -07004065unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004066 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004067 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004068}
4069
Gustavo Padovan2d792812012-10-06 10:07:01 +01004070static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004071 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4072 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004073{
4074 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4075 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004076 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004077 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004078 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004079
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004080 if (cmd_len < sizeof(*rsp))
4081 return -EPROTO;
4082
Linus Torvalds1da177e2005-04-16 15:20:36 -07004083 scid = __le16_to_cpu(rsp->scid);
4084 flags = __le16_to_cpu(rsp->flags);
4085 result = __le16_to_cpu(rsp->result);
4086
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004087 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4088 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004089
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004090 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004091 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004092 return 0;
4093
4094 switch (result) {
4095 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004096 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004097 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004098 break;
4099
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004100 case L2CAP_CONF_PENDING:
4101 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4102
4103 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4104 char buf[64];
4105
4106 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004107 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004108 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004109 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004110 goto done;
4111 }
4112
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004113 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004114 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4115 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004116 } else {
4117 if (l2cap_check_efs(chan)) {
4118 amp_create_logical_link(chan);
4119 chan->ident = cmd->ident;
4120 }
4121 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004122 }
4123 goto done;
4124
Linus Torvalds1da177e2005-04-16 15:20:36 -07004125 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004126 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004127 char req[64];
4128
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004129 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004130 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004131 goto done;
4132 }
4133
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004134 /* throw out any old stored conf requests */
4135 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004136 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004137 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004138 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004139 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004140 goto done;
4141 }
4142
4143 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004144 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004145 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004146 if (result != L2CAP_CONF_SUCCESS)
4147 goto done;
4148 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004149 }
4150
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004151 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004152 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004153
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004154 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004155 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004156 goto done;
4157 }
4158
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004159 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004160 goto done;
4161
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004162 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004163
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004164 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004165 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004166
Mat Martineau105bdf92012-04-27 16:50:48 -07004167 if (chan->mode == L2CAP_MODE_ERTM ||
4168 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004169 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004170
Mat Martineau3c588192012-04-11 10:48:42 -07004171 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004172 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004173 else
4174 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004175 }
4176
4177done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004178 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004179 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004180}
4181
Gustavo Padovan2d792812012-10-06 10:07:01 +01004182static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004183 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4184 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004185{
4186 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4187 struct l2cap_disconn_rsp rsp;
4188 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004189 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004190 struct sock *sk;
4191
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004192 if (cmd_len != sizeof(*req))
4193 return -EPROTO;
4194
Linus Torvalds1da177e2005-04-16 15:20:36 -07004195 scid = __le16_to_cpu(req->scid);
4196 dcid = __le16_to_cpu(req->dcid);
4197
4198 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4199
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004200 mutex_lock(&conn->chan_lock);
4201
4202 chan = __l2cap_get_chan_by_scid(conn, dcid);
4203 if (!chan) {
4204 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004205 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004206 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004207
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004208 l2cap_chan_lock(chan);
4209
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004210 sk = chan->sk;
4211
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004212 rsp.dcid = cpu_to_le16(chan->scid);
4213 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004214 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4215
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004216 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004217 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004218 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004219
Mat Martineau61d6ef32012-04-27 16:50:50 -07004220 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004221 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004222
4223 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004224
Gustavo Padovan80b98022012-05-27 22:27:51 -03004225 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004226 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004227
4228 mutex_unlock(&conn->chan_lock);
4229
Linus Torvalds1da177e2005-04-16 15:20:36 -07004230 return 0;
4231}
4232
Gustavo Padovan2d792812012-10-06 10:07:01 +01004233static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004234 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4235 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004236{
4237 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4238 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004239 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004240
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004241 if (cmd_len != sizeof(*rsp))
4242 return -EPROTO;
4243
Linus Torvalds1da177e2005-04-16 15:20:36 -07004244 scid = __le16_to_cpu(rsp->scid);
4245 dcid = __le16_to_cpu(rsp->dcid);
4246
4247 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4248
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004249 mutex_lock(&conn->chan_lock);
4250
4251 chan = __l2cap_get_chan_by_scid(conn, scid);
4252 if (!chan) {
4253 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004254 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004255 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004256
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004257 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004258
Mat Martineau61d6ef32012-04-27 16:50:50 -07004259 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004260 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004261
4262 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004263
Gustavo Padovan80b98022012-05-27 22:27:51 -03004264 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004265 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004266
4267 mutex_unlock(&conn->chan_lock);
4268
Linus Torvalds1da177e2005-04-16 15:20:36 -07004269 return 0;
4270}
4271
Gustavo Padovan2d792812012-10-06 10:07:01 +01004272static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004273 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4274 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004275{
4276 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004277 u16 type;
4278
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004279 if (cmd_len != sizeof(*req))
4280 return -EPROTO;
4281
Linus Torvalds1da177e2005-04-16 15:20:36 -07004282 type = __le16_to_cpu(req->type);
4283
4284 BT_DBG("type 0x%4.4x", type);
4285
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004286 if (type == L2CAP_IT_FEAT_MASK) {
4287 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004288 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004289 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004290 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4291 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004292 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004293 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004294 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004295 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004296 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004297 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004298
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004299 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004300 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4301 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004302 } else if (type == L2CAP_IT_FIXED_CHAN) {
4303 u8 buf[12];
4304 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004305
4306 if (enable_hs)
4307 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4308 else
4309 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4310
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004311 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4312 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004313 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004314 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4315 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004316 } else {
4317 struct l2cap_info_rsp rsp;
4318 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004319 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004320 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4321 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004322 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004323
4324 return 0;
4325}
4326
Gustavo Padovan2d792812012-10-06 10:07:01 +01004327static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004328 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4329 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004330{
4331 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4332 u16 type, result;
4333
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004334 if (cmd_len != sizeof(*rsp))
4335 return -EPROTO;
4336
Linus Torvalds1da177e2005-04-16 15:20:36 -07004337 type = __le16_to_cpu(rsp->type);
4338 result = __le16_to_cpu(rsp->result);
4339
4340 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4341
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004342 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4343 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004344 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004345 return 0;
4346
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004347 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004348
Ville Tervoadb08ed2010-08-04 09:43:33 +03004349 if (result != L2CAP_IR_SUCCESS) {
4350 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4351 conn->info_ident = 0;
4352
4353 l2cap_conn_start(conn);
4354
4355 return 0;
4356 }
4357
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004358 switch (type) {
4359 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004360 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004361
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004362 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004363 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004364 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004365
4366 conn->info_ident = l2cap_get_ident(conn);
4367
4368 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004369 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004370 } else {
4371 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4372 conn->info_ident = 0;
4373
4374 l2cap_conn_start(conn);
4375 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004376 break;
4377
4378 case L2CAP_IT_FIXED_CHAN:
4379 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004380 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004381 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004382
4383 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004384 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004385 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004386
Linus Torvalds1da177e2005-04-16 15:20:36 -07004387 return 0;
4388}
4389
Mat Martineau17009152012-10-23 15:24:07 -07004390static int l2cap_create_channel_req(struct l2cap_conn *conn,
4391 struct l2cap_cmd_hdr *cmd,
4392 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004393{
4394 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004395 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004396 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004397 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004398 u16 psm, scid;
4399
4400 if (cmd_len != sizeof(*req))
4401 return -EPROTO;
4402
4403 if (!enable_hs)
4404 return -EINVAL;
4405
4406 psm = le16_to_cpu(req->psm);
4407 scid = le16_to_cpu(req->scid);
4408
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004409 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 -07004410
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004411 /* For controller id 0 make BR/EDR connection */
4412 if (req->amp_id == HCI_BREDR_ID) {
4413 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4414 req->amp_id);
4415 return 0;
4416 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004417
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004418 /* Validate AMP controller id */
4419 hdev = hci_dev_get(req->amp_id);
4420 if (!hdev)
4421 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004422
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004423 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004424 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004425 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004426 }
4427
4428 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4429 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004430 if (chan) {
4431 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4432 struct hci_conn *hs_hcon;
4433
4434 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, conn->dst);
4435 if (!hs_hcon) {
4436 hci_dev_put(hdev);
4437 return -EFAULT;
4438 }
4439
4440 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4441
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004442 mgr->bredr_chan = chan;
4443 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004444 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004445 conn->mtu = hdev->block_mtu;
4446 }
4447
4448 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004449
4450 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004451
4452error:
4453 rsp.dcid = 0;
4454 rsp.scid = cpu_to_le16(scid);
4455 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4456 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4457
4458 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4459 sizeof(rsp), &rsp);
4460
4461 return -EFAULT;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004462}
4463
Mat Martineau8eb200b2012-10-23 15:24:17 -07004464static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4465{
4466 struct l2cap_move_chan_req req;
4467 u8 ident;
4468
4469 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4470
4471 ident = l2cap_get_ident(chan->conn);
4472 chan->ident = ident;
4473
4474 req.icid = cpu_to_le16(chan->scid);
4475 req.dest_amp_id = dest_amp_id;
4476
4477 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4478 &req);
4479
4480 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4481}
4482
Mat Martineau1500109b2012-10-23 15:24:15 -07004483static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004484{
4485 struct l2cap_move_chan_rsp rsp;
4486
Mat Martineau1500109b2012-10-23 15:24:15 -07004487 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004488
Mat Martineau1500109b2012-10-23 15:24:15 -07004489 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004490 rsp.result = cpu_to_le16(result);
4491
Mat Martineau1500109b2012-10-23 15:24:15 -07004492 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4493 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004494}
4495
Mat Martineau5b155ef2012-10-23 15:24:14 -07004496static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004497{
4498 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004499
Mat Martineau5b155ef2012-10-23 15:24:14 -07004500 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004501
Mat Martineau5b155ef2012-10-23 15:24:14 -07004502 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004503
Mat Martineau5b155ef2012-10-23 15:24:14 -07004504 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004505 cfm.result = cpu_to_le16(result);
4506
Mat Martineau5b155ef2012-10-23 15:24:14 -07004507 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4508 sizeof(cfm), &cfm);
4509
4510 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4511}
4512
4513static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4514{
4515 struct l2cap_move_chan_cfm cfm;
4516
4517 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4518
4519 cfm.icid = cpu_to_le16(icid);
4520 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4521
4522 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4523 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004524}
4525
4526static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004527 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004528{
4529 struct l2cap_move_chan_cfm_rsp rsp;
4530
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004531 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004532
4533 rsp.icid = cpu_to_le16(icid);
4534 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4535}
4536
Mat Martineau5f3847a2012-10-23 15:24:12 -07004537static void __release_logical_link(struct l2cap_chan *chan)
4538{
4539 chan->hs_hchan = NULL;
4540 chan->hs_hcon = NULL;
4541
4542 /* Placeholder - release the logical link */
4543}
4544
Mat Martineau1500109b2012-10-23 15:24:15 -07004545static void l2cap_logical_fail(struct l2cap_chan *chan)
4546{
4547 /* Logical link setup failed */
4548 if (chan->state != BT_CONNECTED) {
4549 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004550 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004551 return;
4552 }
4553
4554 switch (chan->move_role) {
4555 case L2CAP_MOVE_ROLE_RESPONDER:
4556 l2cap_move_done(chan);
4557 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4558 break;
4559 case L2CAP_MOVE_ROLE_INITIATOR:
4560 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4561 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4562 /* Remote has only sent pending or
4563 * success responses, clean up
4564 */
4565 l2cap_move_done(chan);
4566 }
4567
4568 /* Other amp move states imply that the move
4569 * has already aborted
4570 */
4571 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4572 break;
4573 }
4574}
4575
4576static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4577 struct hci_chan *hchan)
4578{
4579 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004580
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004581 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004582 chan->hs_hcon->l2cap_data = chan->conn;
4583
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004584 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004585
4586 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004587 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004588
4589 set_default_fcs(chan);
4590
4591 err = l2cap_ertm_init(chan);
4592 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004593 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004594 else
4595 l2cap_chan_ready(chan);
4596 }
4597}
4598
4599static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4600 struct hci_chan *hchan)
4601{
4602 chan->hs_hcon = hchan->conn;
4603 chan->hs_hcon->l2cap_data = chan->conn;
4604
4605 BT_DBG("move_state %d", chan->move_state);
4606
4607 switch (chan->move_state) {
4608 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4609 /* Move confirm will be sent after a success
4610 * response is received
4611 */
4612 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4613 break;
4614 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4615 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4616 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4617 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4618 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4619 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4620 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4621 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4622 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4623 }
4624 break;
4625 default:
4626 /* Move was not in expected state, free the channel */
4627 __release_logical_link(chan);
4628
4629 chan->move_state = L2CAP_MOVE_STABLE;
4630 }
4631}
4632
4633/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004634void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4635 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004636{
Mat Martineau1500109b2012-10-23 15:24:15 -07004637 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4638
4639 if (status) {
4640 l2cap_logical_fail(chan);
4641 __release_logical_link(chan);
4642 return;
4643 }
4644
4645 if (chan->state != BT_CONNECTED) {
4646 /* Ignore logical link if channel is on BR/EDR */
4647 if (chan->local_amp_id)
4648 l2cap_logical_finish_create(chan, hchan);
4649 } else {
4650 l2cap_logical_finish_move(chan, hchan);
4651 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004652}
4653
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004654void l2cap_move_start(struct l2cap_chan *chan)
4655{
4656 BT_DBG("chan %p", chan);
4657
4658 if (chan->local_amp_id == HCI_BREDR_ID) {
4659 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4660 return;
4661 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4662 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4663 /* Placeholder - start physical link setup */
4664 } else {
4665 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4666 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4667 chan->move_id = 0;
4668 l2cap_move_setup(chan);
4669 l2cap_send_move_chan_req(chan, 0);
4670 }
4671}
4672
Mat Martineau8eb200b2012-10-23 15:24:17 -07004673static void l2cap_do_create(struct l2cap_chan *chan, int result,
4674 u8 local_amp_id, u8 remote_amp_id)
4675{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004676 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4677 local_amp_id, remote_amp_id);
4678
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004679 chan->fcs = L2CAP_FCS_NONE;
4680
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004681 /* Outgoing channel on AMP */
4682 if (chan->state == BT_CONNECT) {
4683 if (result == L2CAP_CR_SUCCESS) {
4684 chan->local_amp_id = local_amp_id;
4685 l2cap_send_create_chan_req(chan, remote_amp_id);
4686 } else {
4687 /* Revert to BR/EDR connect */
4688 l2cap_send_conn_req(chan);
4689 }
4690
4691 return;
4692 }
4693
4694 /* Incoming channel on AMP */
4695 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004696 struct l2cap_conn_rsp rsp;
4697 char buf[128];
4698 rsp.scid = cpu_to_le16(chan->dcid);
4699 rsp.dcid = cpu_to_le16(chan->scid);
4700
Mat Martineau8eb200b2012-10-23 15:24:17 -07004701 if (result == L2CAP_CR_SUCCESS) {
4702 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004703 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4704 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004705 } else {
4706 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004707 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4708 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004709 }
4710
4711 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4712 sizeof(rsp), &rsp);
4713
4714 if (result == L2CAP_CR_SUCCESS) {
4715 __l2cap_state_change(chan, BT_CONFIG);
4716 set_bit(CONF_REQ_SENT, &chan->conf_state);
4717 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4718 L2CAP_CONF_REQ,
4719 l2cap_build_conf_req(chan, buf), buf);
4720 chan->num_conf_req++;
4721 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004722 }
4723}
4724
4725static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4726 u8 remote_amp_id)
4727{
4728 l2cap_move_setup(chan);
4729 chan->move_id = local_amp_id;
4730 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4731
4732 l2cap_send_move_chan_req(chan, remote_amp_id);
4733}
4734
4735static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4736{
4737 struct hci_chan *hchan = NULL;
4738
4739 /* Placeholder - get hci_chan for logical link */
4740
4741 if (hchan) {
4742 if (hchan->state == BT_CONNECTED) {
4743 /* Logical link is ready to go */
4744 chan->hs_hcon = hchan->conn;
4745 chan->hs_hcon->l2cap_data = chan->conn;
4746 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4747 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4748
4749 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4750 } else {
4751 /* Wait for logical link to be ready */
4752 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4753 }
4754 } else {
4755 /* Logical link not available */
4756 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4757 }
4758}
4759
4760static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4761{
4762 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4763 u8 rsp_result;
4764 if (result == -EINVAL)
4765 rsp_result = L2CAP_MR_BAD_ID;
4766 else
4767 rsp_result = L2CAP_MR_NOT_ALLOWED;
4768
4769 l2cap_send_move_chan_rsp(chan, rsp_result);
4770 }
4771
4772 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4773 chan->move_state = L2CAP_MOVE_STABLE;
4774
4775 /* Restart data transmission */
4776 l2cap_ertm_send(chan);
4777}
4778
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004779/* Invoke with locked chan */
4780void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004781{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004782 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004783 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004784
Mat Martineau8eb200b2012-10-23 15:24:17 -07004785 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4786 chan, result, local_amp_id, remote_amp_id);
4787
Mat Martineau8eb200b2012-10-23 15:24:17 -07004788 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4789 l2cap_chan_unlock(chan);
4790 return;
4791 }
4792
4793 if (chan->state != BT_CONNECTED) {
4794 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4795 } else if (result != L2CAP_MR_SUCCESS) {
4796 l2cap_do_move_cancel(chan, result);
4797 } else {
4798 switch (chan->move_role) {
4799 case L2CAP_MOVE_ROLE_INITIATOR:
4800 l2cap_do_move_initiate(chan, local_amp_id,
4801 remote_amp_id);
4802 break;
4803 case L2CAP_MOVE_ROLE_RESPONDER:
4804 l2cap_do_move_respond(chan, result);
4805 break;
4806 default:
4807 l2cap_do_move_cancel(chan, result);
4808 break;
4809 }
4810 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004811}
4812
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004813static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004814 struct l2cap_cmd_hdr *cmd,
4815 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004816{
4817 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004818 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004819 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004820 u16 icid = 0;
4821 u16 result = L2CAP_MR_NOT_ALLOWED;
4822
4823 if (cmd_len != sizeof(*req))
4824 return -EPROTO;
4825
4826 icid = le16_to_cpu(req->icid);
4827
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004828 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004829
4830 if (!enable_hs)
4831 return -EINVAL;
4832
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004833 chan = l2cap_get_chan_by_dcid(conn, icid);
4834 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004835 rsp.icid = cpu_to_le16(icid);
4836 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4837 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4838 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004839 return 0;
4840 }
4841
Mat Martineau1500109b2012-10-23 15:24:15 -07004842 chan->ident = cmd->ident;
4843
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004844 if (chan->scid < L2CAP_CID_DYN_START ||
4845 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4846 (chan->mode != L2CAP_MODE_ERTM &&
4847 chan->mode != L2CAP_MODE_STREAMING)) {
4848 result = L2CAP_MR_NOT_ALLOWED;
4849 goto send_move_response;
4850 }
4851
4852 if (chan->local_amp_id == req->dest_amp_id) {
4853 result = L2CAP_MR_SAME_ID;
4854 goto send_move_response;
4855 }
4856
4857 if (req->dest_amp_id) {
4858 struct hci_dev *hdev;
4859 hdev = hci_dev_get(req->dest_amp_id);
4860 if (!hdev || hdev->dev_type != HCI_AMP ||
4861 !test_bit(HCI_UP, &hdev->flags)) {
4862 if (hdev)
4863 hci_dev_put(hdev);
4864
4865 result = L2CAP_MR_BAD_ID;
4866 goto send_move_response;
4867 }
4868 hci_dev_put(hdev);
4869 }
4870
4871 /* Detect a move collision. Only send a collision response
4872 * if this side has "lost", otherwise proceed with the move.
4873 * The winner has the larger bd_addr.
4874 */
4875 if ((__chan_is_moving(chan) ||
4876 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
4877 bacmp(conn->src, conn->dst) > 0) {
4878 result = L2CAP_MR_COLLISION;
4879 goto send_move_response;
4880 }
4881
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004882 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4883 l2cap_move_setup(chan);
4884 chan->move_id = req->dest_amp_id;
4885 icid = chan->dcid;
4886
4887 if (!req->dest_amp_id) {
4888 /* Moving to BR/EDR */
4889 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4890 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4891 result = L2CAP_MR_PEND;
4892 } else {
4893 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4894 result = L2CAP_MR_SUCCESS;
4895 }
4896 } else {
4897 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4898 /* Placeholder - uncomment when amp functions are available */
4899 /*amp_accept_physical(chan, req->dest_amp_id);*/
4900 result = L2CAP_MR_PEND;
4901 }
4902
4903send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004904 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004905
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004906 l2cap_chan_unlock(chan);
4907
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004908 return 0;
4909}
4910
Mat Martineau5b155ef2012-10-23 15:24:14 -07004911static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4912{
4913 struct l2cap_chan *chan;
4914 struct hci_chan *hchan = NULL;
4915
4916 chan = l2cap_get_chan_by_scid(conn, icid);
4917 if (!chan) {
4918 l2cap_send_move_chan_cfm_icid(conn, icid);
4919 return;
4920 }
4921
4922 __clear_chan_timer(chan);
4923 if (result == L2CAP_MR_PEND)
4924 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4925
4926 switch (chan->move_state) {
4927 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4928 /* Move confirm will be sent when logical link
4929 * is complete.
4930 */
4931 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4932 break;
4933 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4934 if (result == L2CAP_MR_PEND) {
4935 break;
4936 } else if (test_bit(CONN_LOCAL_BUSY,
4937 &chan->conn_state)) {
4938 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4939 } else {
4940 /* Logical link is up or moving to BR/EDR,
4941 * proceed with move
4942 */
4943 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4944 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4945 }
4946 break;
4947 case L2CAP_MOVE_WAIT_RSP:
4948 /* Moving to AMP */
4949 if (result == L2CAP_MR_SUCCESS) {
4950 /* Remote is ready, send confirm immediately
4951 * after logical link is ready
4952 */
4953 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4954 } else {
4955 /* Both logical link and move success
4956 * are required to confirm
4957 */
4958 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
4959 }
4960
4961 /* Placeholder - get hci_chan for logical link */
4962 if (!hchan) {
4963 /* Logical link not available */
4964 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4965 break;
4966 }
4967
4968 /* If the logical link is not yet connected, do not
4969 * send confirmation.
4970 */
4971 if (hchan->state != BT_CONNECTED)
4972 break;
4973
4974 /* Logical link is already ready to go */
4975
4976 chan->hs_hcon = hchan->conn;
4977 chan->hs_hcon->l2cap_data = chan->conn;
4978
4979 if (result == L2CAP_MR_SUCCESS) {
4980 /* Can confirm now */
4981 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4982 } else {
4983 /* Now only need move success
4984 * to confirm
4985 */
4986 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4987 }
4988
4989 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4990 break;
4991 default:
4992 /* Any other amp move state means the move failed. */
4993 chan->move_id = chan->local_amp_id;
4994 l2cap_move_done(chan);
4995 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4996 }
4997
4998 l2cap_chan_unlock(chan);
4999}
5000
5001static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5002 u16 result)
5003{
5004 struct l2cap_chan *chan;
5005
5006 chan = l2cap_get_chan_by_ident(conn, ident);
5007 if (!chan) {
5008 /* Could not locate channel, icid is best guess */
5009 l2cap_send_move_chan_cfm_icid(conn, icid);
5010 return;
5011 }
5012
5013 __clear_chan_timer(chan);
5014
5015 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5016 if (result == L2CAP_MR_COLLISION) {
5017 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5018 } else {
5019 /* Cleanup - cancel move */
5020 chan->move_id = chan->local_amp_id;
5021 l2cap_move_done(chan);
5022 }
5023 }
5024
5025 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5026
5027 l2cap_chan_unlock(chan);
5028}
5029
5030static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5031 struct l2cap_cmd_hdr *cmd,
5032 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005033{
5034 struct l2cap_move_chan_rsp *rsp = data;
5035 u16 icid, result;
5036
5037 if (cmd_len != sizeof(*rsp))
5038 return -EPROTO;
5039
5040 icid = le16_to_cpu(rsp->icid);
5041 result = le16_to_cpu(rsp->result);
5042
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005043 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005044
Mat Martineau5b155ef2012-10-23 15:24:14 -07005045 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5046 l2cap_move_continue(conn, icid, result);
5047 else
5048 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005049
5050 return 0;
5051}
5052
Mat Martineau5f3847a2012-10-23 15:24:12 -07005053static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5054 struct l2cap_cmd_hdr *cmd,
5055 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005056{
5057 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005058 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005059 u16 icid, result;
5060
5061 if (cmd_len != sizeof(*cfm))
5062 return -EPROTO;
5063
5064 icid = le16_to_cpu(cfm->icid);
5065 result = le16_to_cpu(cfm->result);
5066
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005067 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005068
Mat Martineau5f3847a2012-10-23 15:24:12 -07005069 chan = l2cap_get_chan_by_dcid(conn, icid);
5070 if (!chan) {
5071 /* Spec requires a response even if the icid was not found */
5072 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5073 return 0;
5074 }
5075
5076 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5077 if (result == L2CAP_MC_CONFIRMED) {
5078 chan->local_amp_id = chan->move_id;
5079 if (!chan->local_amp_id)
5080 __release_logical_link(chan);
5081 } else {
5082 chan->move_id = chan->local_amp_id;
5083 }
5084
5085 l2cap_move_done(chan);
5086 }
5087
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005088 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5089
Mat Martineau5f3847a2012-10-23 15:24:12 -07005090 l2cap_chan_unlock(chan);
5091
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005092 return 0;
5093}
5094
5095static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005096 struct l2cap_cmd_hdr *cmd,
5097 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005098{
5099 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005100 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005101 u16 icid;
5102
5103 if (cmd_len != sizeof(*rsp))
5104 return -EPROTO;
5105
5106 icid = le16_to_cpu(rsp->icid);
5107
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005108 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005109
Mat Martineau3fd71a02012-10-23 15:24:16 -07005110 chan = l2cap_get_chan_by_scid(conn, icid);
5111 if (!chan)
5112 return 0;
5113
5114 __clear_chan_timer(chan);
5115
5116 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5117 chan->local_amp_id = chan->move_id;
5118
5119 if (!chan->local_amp_id && chan->hs_hchan)
5120 __release_logical_link(chan);
5121
5122 l2cap_move_done(chan);
5123 }
5124
5125 l2cap_chan_unlock(chan);
5126
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005127 return 0;
5128}
5129
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005130static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005131 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005132{
5133 u16 max_latency;
5134
5135 if (min > max || min < 6 || max > 3200)
5136 return -EINVAL;
5137
5138 if (to_multiplier < 10 || to_multiplier > 3200)
5139 return -EINVAL;
5140
5141 if (max >= to_multiplier * 8)
5142 return -EINVAL;
5143
5144 max_latency = (to_multiplier * 8 / max) - 1;
5145 if (latency > 499 || latency > max_latency)
5146 return -EINVAL;
5147
5148 return 0;
5149}
5150
5151static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005152 struct l2cap_cmd_hdr *cmd,
5153 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005154{
5155 struct hci_conn *hcon = conn->hcon;
5156 struct l2cap_conn_param_update_req *req;
5157 struct l2cap_conn_param_update_rsp rsp;
5158 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005159 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005160
5161 if (!(hcon->link_mode & HCI_LM_MASTER))
5162 return -EINVAL;
5163
5164 cmd_len = __le16_to_cpu(cmd->len);
5165 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5166 return -EPROTO;
5167
5168 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005169 min = __le16_to_cpu(req->min);
5170 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005171 latency = __le16_to_cpu(req->latency);
5172 to_multiplier = __le16_to_cpu(req->to_multiplier);
5173
5174 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 +01005175 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005176
5177 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005178
5179 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5180 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005181 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005182 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005183 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005184
5185 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005186 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005187
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005188 if (!err)
5189 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5190
Claudio Takahaside731152011-02-11 19:28:55 -02005191 return 0;
5192}
5193
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005194static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005195 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5196 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005197{
5198 int err = 0;
5199
5200 switch (cmd->code) {
5201 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005202 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005203 break;
5204
5205 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005206 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005207 break;
5208
5209 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005210 case L2CAP_CREATE_CHAN_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005211 err = l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005212 break;
5213
5214 case L2CAP_CONF_REQ:
5215 err = l2cap_config_req(conn, cmd, cmd_len, data);
5216 break;
5217
5218 case L2CAP_CONF_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005219 err = l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005220 break;
5221
5222 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005223 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005224 break;
5225
5226 case L2CAP_DISCONN_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005227 err = l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005228 break;
5229
5230 case L2CAP_ECHO_REQ:
5231 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5232 break;
5233
5234 case L2CAP_ECHO_RSP:
5235 break;
5236
5237 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005238 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005239 break;
5240
5241 case L2CAP_INFO_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005242 err = l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005243 break;
5244
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005245 case L2CAP_CREATE_CHAN_REQ:
5246 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5247 break;
5248
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005249 case L2CAP_MOVE_CHAN_REQ:
5250 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5251 break;
5252
5253 case L2CAP_MOVE_CHAN_RSP:
5254 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
5255 break;
5256
5257 case L2CAP_MOVE_CHAN_CFM:
5258 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5259 break;
5260
5261 case L2CAP_MOVE_CHAN_CFM_RSP:
5262 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
5263 break;
5264
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005265 default:
5266 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5267 err = -EINVAL;
5268 break;
5269 }
5270
5271 return err;
5272}
5273
5274static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005275 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005276{
5277 switch (cmd->code) {
5278 case L2CAP_COMMAND_REJ:
5279 return 0;
5280
5281 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02005282 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005283
5284 case L2CAP_CONN_PARAM_UPDATE_RSP:
5285 return 0;
5286
5287 default:
5288 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5289 return -EINVAL;
5290 }
5291}
5292
Johan Hedbergc5623552013-04-29 19:35:33 +03005293static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5294 struct sk_buff *skb)
5295{
5296 u8 *data = skb->data;
5297 int len = skb->len;
5298 struct l2cap_cmd_hdr cmd;
5299 int err;
5300
5301 l2cap_raw_recv(conn, skb);
5302
5303 while (len >= L2CAP_CMD_HDR_SIZE) {
5304 u16 cmd_len;
5305 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5306 data += L2CAP_CMD_HDR_SIZE;
5307 len -= L2CAP_CMD_HDR_SIZE;
5308
5309 cmd_len = le16_to_cpu(cmd.len);
5310
5311 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5312 cmd.ident);
5313
5314 if (cmd_len > len || !cmd.ident) {
5315 BT_DBG("corrupted command");
5316 break;
5317 }
5318
5319 err = l2cap_le_sig_cmd(conn, &cmd, data);
5320 if (err) {
5321 struct l2cap_cmd_rej_unk rej;
5322
5323 BT_ERR("Wrong link type (%d)", err);
5324
5325 /* FIXME: Map err to a valid reason */
5326 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
5327 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5328 sizeof(rej), &rej);
5329 }
5330
5331 data += cmd_len;
5332 len -= cmd_len;
5333 }
5334
5335 kfree_skb(skb);
5336}
5337
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005338static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005339 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005340{
5341 u8 *data = skb->data;
5342 int len = skb->len;
5343 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005344 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005345
5346 l2cap_raw_recv(conn, skb);
5347
5348 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005349 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005350 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5351 data += L2CAP_CMD_HDR_SIZE;
5352 len -= L2CAP_CMD_HDR_SIZE;
5353
Al Viro88219a02007-07-29 00:17:25 -07005354 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005355
Gustavo Padovan2d792812012-10-06 10:07:01 +01005356 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5357 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005358
Al Viro88219a02007-07-29 00:17:25 -07005359 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005360 BT_DBG("corrupted command");
5361 break;
5362 }
5363
Johan Hedbergc5623552013-04-29 19:35:33 +03005364 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005365 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005366 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005367
5368 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005369
5370 /* FIXME: Map err to a valid reason */
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005371 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005372 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5373 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005374 }
5375
Al Viro88219a02007-07-29 00:17:25 -07005376 data += cmd_len;
5377 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005378 }
5379
5380 kfree_skb(skb);
5381}
5382
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005383static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005384{
5385 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005386 int hdr_size;
5387
5388 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5389 hdr_size = L2CAP_EXT_HDR_SIZE;
5390 else
5391 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005392
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005393 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005394 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005395 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5396 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5397
5398 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005399 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005400 }
5401 return 0;
5402}
5403
Mat Martineau6ea00482012-05-17 20:53:52 -07005404static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005405{
Mat Martineaue31f7632012-05-17 20:53:41 -07005406 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005407
Mat Martineaue31f7632012-05-17 20:53:41 -07005408 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005409
Mat Martineaue31f7632012-05-17 20:53:41 -07005410 memset(&control, 0, sizeof(control));
5411 control.sframe = 1;
5412 control.final = 1;
5413 control.reqseq = chan->buffer_seq;
5414 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005415
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005416 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005417 control.super = L2CAP_SUPER_RNR;
5418 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005419 }
5420
Mat Martineaue31f7632012-05-17 20:53:41 -07005421 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5422 chan->unacked_frames > 0)
5423 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005424
Mat Martineaue31f7632012-05-17 20:53:41 -07005425 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005426 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005427
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005428 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005429 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5430 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5431 * send it now.
5432 */
5433 control.super = L2CAP_SUPER_RR;
5434 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005435 }
5436}
5437
Gustavo Padovan2d792812012-10-06 10:07:01 +01005438static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5439 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005440{
Mat Martineau84084a32011-07-22 14:54:00 -07005441 /* skb->len reflects data in skb as well as all fragments
5442 * skb->data_len reflects only data in fragments
5443 */
5444 if (!skb_has_frag_list(skb))
5445 skb_shinfo(skb)->frag_list = new_frag;
5446
5447 new_frag->next = NULL;
5448
5449 (*last_frag)->next = new_frag;
5450 *last_frag = new_frag;
5451
5452 skb->len += new_frag->len;
5453 skb->data_len += new_frag->len;
5454 skb->truesize += new_frag->truesize;
5455}
5456
Mat Martineau4b51dae92012-05-17 20:53:37 -07005457static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5458 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005459{
5460 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005461
Mat Martineau4b51dae92012-05-17 20:53:37 -07005462 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005463 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005464 if (chan->sdu)
5465 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005466
Gustavo Padovan80b98022012-05-27 22:27:51 -03005467 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005468 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005469
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005470 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005471 if (chan->sdu)
5472 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005473
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005474 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005475 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005476
Mat Martineau84084a32011-07-22 14:54:00 -07005477 if (chan->sdu_len > chan->imtu) {
5478 err = -EMSGSIZE;
5479 break;
5480 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005481
Mat Martineau84084a32011-07-22 14:54:00 -07005482 if (skb->len >= chan->sdu_len)
5483 break;
5484
5485 chan->sdu = skb;
5486 chan->sdu_last_frag = skb;
5487
5488 skb = NULL;
5489 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005490 break;
5491
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005492 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005493 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005494 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005495
Mat Martineau84084a32011-07-22 14:54:00 -07005496 append_skb_frag(chan->sdu, skb,
5497 &chan->sdu_last_frag);
5498 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005499
Mat Martineau84084a32011-07-22 14:54:00 -07005500 if (chan->sdu->len >= chan->sdu_len)
5501 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005502
Mat Martineau84084a32011-07-22 14:54:00 -07005503 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005504 break;
5505
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005506 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005507 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005508 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005509
Mat Martineau84084a32011-07-22 14:54:00 -07005510 append_skb_frag(chan->sdu, skb,
5511 &chan->sdu_last_frag);
5512 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005513
Mat Martineau84084a32011-07-22 14:54:00 -07005514 if (chan->sdu->len != chan->sdu_len)
5515 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005516
Gustavo Padovan80b98022012-05-27 22:27:51 -03005517 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005518
Mat Martineau84084a32011-07-22 14:54:00 -07005519 if (!err) {
5520 /* Reassembly complete */
5521 chan->sdu = NULL;
5522 chan->sdu_last_frag = NULL;
5523 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005524 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005525 break;
5526 }
5527
Mat Martineau84084a32011-07-22 14:54:00 -07005528 if (err) {
5529 kfree_skb(skb);
5530 kfree_skb(chan->sdu);
5531 chan->sdu = NULL;
5532 chan->sdu_last_frag = NULL;
5533 chan->sdu_len = 0;
5534 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005535
Mat Martineau84084a32011-07-22 14:54:00 -07005536 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005537}
5538
Mat Martineau32b32732012-10-23 15:24:11 -07005539static int l2cap_resegment(struct l2cap_chan *chan)
5540{
5541 /* Placeholder */
5542 return 0;
5543}
5544
Mat Martineaue3281402011-07-07 09:39:02 -07005545void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03005546{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005547 u8 event;
5548
5549 if (chan->mode != L2CAP_MODE_ERTM)
5550 return;
5551
5552 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005553 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005554}
5555
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005556static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5557{
Mat Martineau63838722012-05-17 20:53:45 -07005558 int err = 0;
5559 /* Pass sequential frames to l2cap_reassemble_sdu()
5560 * until a gap is encountered.
5561 */
5562
5563 BT_DBG("chan %p", chan);
5564
5565 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5566 struct sk_buff *skb;
5567 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5568 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5569
5570 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5571
5572 if (!skb)
5573 break;
5574
5575 skb_unlink(skb, &chan->srej_q);
5576 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5577 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5578 if (err)
5579 break;
5580 }
5581
5582 if (skb_queue_empty(&chan->srej_q)) {
5583 chan->rx_state = L2CAP_RX_STATE_RECV;
5584 l2cap_send_ack(chan);
5585 }
5586
5587 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005588}
5589
5590static void l2cap_handle_srej(struct l2cap_chan *chan,
5591 struct l2cap_ctrl *control)
5592{
Mat Martineauf80842a2012-05-17 20:53:46 -07005593 struct sk_buff *skb;
5594
5595 BT_DBG("chan %p, control %p", chan, control);
5596
5597 if (control->reqseq == chan->next_tx_seq) {
5598 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005599 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005600 return;
5601 }
5602
5603 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5604
5605 if (skb == NULL) {
5606 BT_DBG("Seq %d not available for retransmission",
5607 control->reqseq);
5608 return;
5609 }
5610
5611 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5612 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005613 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005614 return;
5615 }
5616
5617 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5618
5619 if (control->poll) {
5620 l2cap_pass_to_tx(chan, control);
5621
5622 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5623 l2cap_retransmit(chan, control);
5624 l2cap_ertm_send(chan);
5625
5626 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5627 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5628 chan->srej_save_reqseq = control->reqseq;
5629 }
5630 } else {
5631 l2cap_pass_to_tx_fbit(chan, control);
5632
5633 if (control->final) {
5634 if (chan->srej_save_reqseq != control->reqseq ||
5635 !test_and_clear_bit(CONN_SREJ_ACT,
5636 &chan->conn_state))
5637 l2cap_retransmit(chan, control);
5638 } else {
5639 l2cap_retransmit(chan, control);
5640 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5641 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5642 chan->srej_save_reqseq = control->reqseq;
5643 }
5644 }
5645 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005646}
5647
5648static void l2cap_handle_rej(struct l2cap_chan *chan,
5649 struct l2cap_ctrl *control)
5650{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005651 struct sk_buff *skb;
5652
5653 BT_DBG("chan %p, control %p", chan, control);
5654
5655 if (control->reqseq == chan->next_tx_seq) {
5656 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005657 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005658 return;
5659 }
5660
5661 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5662
5663 if (chan->max_tx && skb &&
5664 bt_cb(skb)->control.retries >= chan->max_tx) {
5665 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005666 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005667 return;
5668 }
5669
5670 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5671
5672 l2cap_pass_to_tx(chan, control);
5673
5674 if (control->final) {
5675 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5676 l2cap_retransmit_all(chan, control);
5677 } else {
5678 l2cap_retransmit_all(chan, control);
5679 l2cap_ertm_send(chan);
5680 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5681 set_bit(CONN_REJ_ACT, &chan->conn_state);
5682 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005683}
5684
Mat Martineau4b51dae92012-05-17 20:53:37 -07005685static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5686{
5687 BT_DBG("chan %p, txseq %d", chan, txseq);
5688
5689 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5690 chan->expected_tx_seq);
5691
5692 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5693 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005694 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005695 /* See notes below regarding "double poll" and
5696 * invalid packets.
5697 */
5698 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5699 BT_DBG("Invalid/Ignore - after SREJ");
5700 return L2CAP_TXSEQ_INVALID_IGNORE;
5701 } else {
5702 BT_DBG("Invalid - in window after SREJ sent");
5703 return L2CAP_TXSEQ_INVALID;
5704 }
5705 }
5706
5707 if (chan->srej_list.head == txseq) {
5708 BT_DBG("Expected SREJ");
5709 return L2CAP_TXSEQ_EXPECTED_SREJ;
5710 }
5711
5712 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5713 BT_DBG("Duplicate SREJ - txseq already stored");
5714 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5715 }
5716
5717 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5718 BT_DBG("Unexpected SREJ - not requested");
5719 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5720 }
5721 }
5722
5723 if (chan->expected_tx_seq == txseq) {
5724 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5725 chan->tx_win) {
5726 BT_DBG("Invalid - txseq outside tx window");
5727 return L2CAP_TXSEQ_INVALID;
5728 } else {
5729 BT_DBG("Expected");
5730 return L2CAP_TXSEQ_EXPECTED;
5731 }
5732 }
5733
5734 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01005735 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005736 BT_DBG("Duplicate - expected_tx_seq later than txseq");
5737 return L2CAP_TXSEQ_DUPLICATE;
5738 }
5739
5740 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
5741 /* A source of invalid packets is a "double poll" condition,
5742 * where delays cause us to send multiple poll packets. If
5743 * the remote stack receives and processes both polls,
5744 * sequence numbers can wrap around in such a way that a
5745 * resent frame has a sequence number that looks like new data
5746 * with a sequence gap. This would trigger an erroneous SREJ
5747 * request.
5748 *
5749 * Fortunately, this is impossible with a tx window that's
5750 * less than half of the maximum sequence number, which allows
5751 * invalid frames to be safely ignored.
5752 *
5753 * With tx window sizes greater than half of the tx window
5754 * maximum, the frame is invalid and cannot be ignored. This
5755 * causes a disconnect.
5756 */
5757
5758 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5759 BT_DBG("Invalid/Ignore - txseq outside tx window");
5760 return L2CAP_TXSEQ_INVALID_IGNORE;
5761 } else {
5762 BT_DBG("Invalid - txseq outside tx window");
5763 return L2CAP_TXSEQ_INVALID;
5764 }
5765 } else {
5766 BT_DBG("Unexpected - txseq indicates missing frames");
5767 return L2CAP_TXSEQ_UNEXPECTED;
5768 }
5769}
5770
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005771static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5772 struct l2cap_ctrl *control,
5773 struct sk_buff *skb, u8 event)
5774{
5775 int err = 0;
5776 bool skb_in_use = 0;
5777
5778 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5779 event);
5780
5781 switch (event) {
5782 case L2CAP_EV_RECV_IFRAME:
5783 switch (l2cap_classify_txseq(chan, control->txseq)) {
5784 case L2CAP_TXSEQ_EXPECTED:
5785 l2cap_pass_to_tx(chan, control);
5786
5787 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5788 BT_DBG("Busy, discarding expected seq %d",
5789 control->txseq);
5790 break;
5791 }
5792
5793 chan->expected_tx_seq = __next_seq(chan,
5794 control->txseq);
5795
5796 chan->buffer_seq = chan->expected_tx_seq;
5797 skb_in_use = 1;
5798
5799 err = l2cap_reassemble_sdu(chan, skb, control);
5800 if (err)
5801 break;
5802
5803 if (control->final) {
5804 if (!test_and_clear_bit(CONN_REJ_ACT,
5805 &chan->conn_state)) {
5806 control->final = 0;
5807 l2cap_retransmit_all(chan, control);
5808 l2cap_ertm_send(chan);
5809 }
5810 }
5811
5812 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5813 l2cap_send_ack(chan);
5814 break;
5815 case L2CAP_TXSEQ_UNEXPECTED:
5816 l2cap_pass_to_tx(chan, control);
5817
5818 /* Can't issue SREJ frames in the local busy state.
5819 * Drop this frame, it will be seen as missing
5820 * when local busy is exited.
5821 */
5822 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5823 BT_DBG("Busy, discarding unexpected seq %d",
5824 control->txseq);
5825 break;
5826 }
5827
5828 /* There was a gap in the sequence, so an SREJ
5829 * must be sent for each missing frame. The
5830 * current frame is stored for later use.
5831 */
5832 skb_queue_tail(&chan->srej_q, skb);
5833 skb_in_use = 1;
5834 BT_DBG("Queued %p (queue len %d)", skb,
5835 skb_queue_len(&chan->srej_q));
5836
5837 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5838 l2cap_seq_list_clear(&chan->srej_list);
5839 l2cap_send_srej(chan, control->txseq);
5840
5841 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5842 break;
5843 case L2CAP_TXSEQ_DUPLICATE:
5844 l2cap_pass_to_tx(chan, control);
5845 break;
5846 case L2CAP_TXSEQ_INVALID_IGNORE:
5847 break;
5848 case L2CAP_TXSEQ_INVALID:
5849 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005850 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005851 break;
5852 }
5853 break;
5854 case L2CAP_EV_RECV_RR:
5855 l2cap_pass_to_tx(chan, control);
5856 if (control->final) {
5857 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5858
Mat Martineaue6a3ee62012-10-23 15:24:22 -07005859 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
5860 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005861 control->final = 0;
5862 l2cap_retransmit_all(chan, control);
5863 }
5864
5865 l2cap_ertm_send(chan);
5866 } else if (control->poll) {
5867 l2cap_send_i_or_rr_or_rnr(chan);
5868 } else {
5869 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5870 &chan->conn_state) &&
5871 chan->unacked_frames)
5872 __set_retrans_timer(chan);
5873
5874 l2cap_ertm_send(chan);
5875 }
5876 break;
5877 case L2CAP_EV_RECV_RNR:
5878 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5879 l2cap_pass_to_tx(chan, control);
5880 if (control && control->poll) {
5881 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5882 l2cap_send_rr_or_rnr(chan, 0);
5883 }
5884 __clear_retrans_timer(chan);
5885 l2cap_seq_list_clear(&chan->retrans_list);
5886 break;
5887 case L2CAP_EV_RECV_REJ:
5888 l2cap_handle_rej(chan, control);
5889 break;
5890 case L2CAP_EV_RECV_SREJ:
5891 l2cap_handle_srej(chan, control);
5892 break;
5893 default:
5894 break;
5895 }
5896
5897 if (skb && !skb_in_use) {
5898 BT_DBG("Freeing %p", skb);
5899 kfree_skb(skb);
5900 }
5901
5902 return err;
5903}
5904
5905static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5906 struct l2cap_ctrl *control,
5907 struct sk_buff *skb, u8 event)
5908{
5909 int err = 0;
5910 u16 txseq = control->txseq;
5911 bool skb_in_use = 0;
5912
5913 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5914 event);
5915
5916 switch (event) {
5917 case L2CAP_EV_RECV_IFRAME:
5918 switch (l2cap_classify_txseq(chan, txseq)) {
5919 case L2CAP_TXSEQ_EXPECTED:
5920 /* Keep frame for reassembly later */
5921 l2cap_pass_to_tx(chan, control);
5922 skb_queue_tail(&chan->srej_q, skb);
5923 skb_in_use = 1;
5924 BT_DBG("Queued %p (queue len %d)", skb,
5925 skb_queue_len(&chan->srej_q));
5926
5927 chan->expected_tx_seq = __next_seq(chan, txseq);
5928 break;
5929 case L2CAP_TXSEQ_EXPECTED_SREJ:
5930 l2cap_seq_list_pop(&chan->srej_list);
5931
5932 l2cap_pass_to_tx(chan, control);
5933 skb_queue_tail(&chan->srej_q, skb);
5934 skb_in_use = 1;
5935 BT_DBG("Queued %p (queue len %d)", skb,
5936 skb_queue_len(&chan->srej_q));
5937
5938 err = l2cap_rx_queued_iframes(chan);
5939 if (err)
5940 break;
5941
5942 break;
5943 case L2CAP_TXSEQ_UNEXPECTED:
5944 /* Got a frame that can't be reassembled yet.
5945 * Save it for later, and send SREJs to cover
5946 * the missing frames.
5947 */
5948 skb_queue_tail(&chan->srej_q, skb);
5949 skb_in_use = 1;
5950 BT_DBG("Queued %p (queue len %d)", skb,
5951 skb_queue_len(&chan->srej_q));
5952
5953 l2cap_pass_to_tx(chan, control);
5954 l2cap_send_srej(chan, control->txseq);
5955 break;
5956 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
5957 /* This frame was requested with an SREJ, but
5958 * some expected retransmitted frames are
5959 * missing. Request retransmission of missing
5960 * SREJ'd frames.
5961 */
5962 skb_queue_tail(&chan->srej_q, skb);
5963 skb_in_use = 1;
5964 BT_DBG("Queued %p (queue len %d)", skb,
5965 skb_queue_len(&chan->srej_q));
5966
5967 l2cap_pass_to_tx(chan, control);
5968 l2cap_send_srej_list(chan, control->txseq);
5969 break;
5970 case L2CAP_TXSEQ_DUPLICATE_SREJ:
5971 /* We've already queued this frame. Drop this copy. */
5972 l2cap_pass_to_tx(chan, control);
5973 break;
5974 case L2CAP_TXSEQ_DUPLICATE:
5975 /* Expecting a later sequence number, so this frame
5976 * was already received. Ignore it completely.
5977 */
5978 break;
5979 case L2CAP_TXSEQ_INVALID_IGNORE:
5980 break;
5981 case L2CAP_TXSEQ_INVALID:
5982 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005983 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005984 break;
5985 }
5986 break;
5987 case L2CAP_EV_RECV_RR:
5988 l2cap_pass_to_tx(chan, control);
5989 if (control->final) {
5990 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5991
5992 if (!test_and_clear_bit(CONN_REJ_ACT,
5993 &chan->conn_state)) {
5994 control->final = 0;
5995 l2cap_retransmit_all(chan, control);
5996 }
5997
5998 l2cap_ertm_send(chan);
5999 } else if (control->poll) {
6000 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6001 &chan->conn_state) &&
6002 chan->unacked_frames) {
6003 __set_retrans_timer(chan);
6004 }
6005
6006 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6007 l2cap_send_srej_tail(chan);
6008 } else {
6009 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6010 &chan->conn_state) &&
6011 chan->unacked_frames)
6012 __set_retrans_timer(chan);
6013
6014 l2cap_send_ack(chan);
6015 }
6016 break;
6017 case L2CAP_EV_RECV_RNR:
6018 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6019 l2cap_pass_to_tx(chan, control);
6020 if (control->poll) {
6021 l2cap_send_srej_tail(chan);
6022 } else {
6023 struct l2cap_ctrl rr_control;
6024 memset(&rr_control, 0, sizeof(rr_control));
6025 rr_control.sframe = 1;
6026 rr_control.super = L2CAP_SUPER_RR;
6027 rr_control.reqseq = chan->buffer_seq;
6028 l2cap_send_sframe(chan, &rr_control);
6029 }
6030
6031 break;
6032 case L2CAP_EV_RECV_REJ:
6033 l2cap_handle_rej(chan, control);
6034 break;
6035 case L2CAP_EV_RECV_SREJ:
6036 l2cap_handle_srej(chan, control);
6037 break;
6038 }
6039
6040 if (skb && !skb_in_use) {
6041 BT_DBG("Freeing %p", skb);
6042 kfree_skb(skb);
6043 }
6044
6045 return err;
6046}
6047
Mat Martineau32b32732012-10-23 15:24:11 -07006048static int l2cap_finish_move(struct l2cap_chan *chan)
6049{
6050 BT_DBG("chan %p", chan);
6051
6052 chan->rx_state = L2CAP_RX_STATE_RECV;
6053
6054 if (chan->hs_hcon)
6055 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6056 else
6057 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6058
6059 return l2cap_resegment(chan);
6060}
6061
6062static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6063 struct l2cap_ctrl *control,
6064 struct sk_buff *skb, u8 event)
6065{
6066 int err;
6067
6068 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6069 event);
6070
6071 if (!control->poll)
6072 return -EPROTO;
6073
6074 l2cap_process_reqseq(chan, control->reqseq);
6075
6076 if (!skb_queue_empty(&chan->tx_q))
6077 chan->tx_send_head = skb_peek(&chan->tx_q);
6078 else
6079 chan->tx_send_head = NULL;
6080
6081 /* Rewind next_tx_seq to the point expected
6082 * by the receiver.
6083 */
6084 chan->next_tx_seq = control->reqseq;
6085 chan->unacked_frames = 0;
6086
6087 err = l2cap_finish_move(chan);
6088 if (err)
6089 return err;
6090
6091 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6092 l2cap_send_i_or_rr_or_rnr(chan);
6093
6094 if (event == L2CAP_EV_RECV_IFRAME)
6095 return -EPROTO;
6096
6097 return l2cap_rx_state_recv(chan, control, NULL, event);
6098}
6099
6100static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6101 struct l2cap_ctrl *control,
6102 struct sk_buff *skb, u8 event)
6103{
6104 int err;
6105
6106 if (!control->final)
6107 return -EPROTO;
6108
6109 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6110
6111 chan->rx_state = L2CAP_RX_STATE_RECV;
6112 l2cap_process_reqseq(chan, control->reqseq);
6113
6114 if (!skb_queue_empty(&chan->tx_q))
6115 chan->tx_send_head = skb_peek(&chan->tx_q);
6116 else
6117 chan->tx_send_head = NULL;
6118
6119 /* Rewind next_tx_seq to the point expected
6120 * by the receiver.
6121 */
6122 chan->next_tx_seq = control->reqseq;
6123 chan->unacked_frames = 0;
6124
6125 if (chan->hs_hcon)
6126 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6127 else
6128 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6129
6130 err = l2cap_resegment(chan);
6131
6132 if (!err)
6133 err = l2cap_rx_state_recv(chan, control, skb, event);
6134
6135 return err;
6136}
6137
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006138static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6139{
6140 /* Make sure reqseq is for a packet that has been sent but not acked */
6141 u16 unacked;
6142
6143 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6144 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6145}
6146
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006147static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6148 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006149{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006150 int err = 0;
6151
6152 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6153 control, skb, event, chan->rx_state);
6154
6155 if (__valid_reqseq(chan, control->reqseq)) {
6156 switch (chan->rx_state) {
6157 case L2CAP_RX_STATE_RECV:
6158 err = l2cap_rx_state_recv(chan, control, skb, event);
6159 break;
6160 case L2CAP_RX_STATE_SREJ_SENT:
6161 err = l2cap_rx_state_srej_sent(chan, control, skb,
6162 event);
6163 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006164 case L2CAP_RX_STATE_WAIT_P:
6165 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6166 break;
6167 case L2CAP_RX_STATE_WAIT_F:
6168 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6169 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006170 default:
6171 /* shut it down */
6172 break;
6173 }
6174 } else {
6175 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6176 control->reqseq, chan->next_tx_seq,
6177 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006178 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006179 }
6180
6181 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006182}
6183
6184static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6185 struct sk_buff *skb)
6186{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006187 int err = 0;
6188
6189 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6190 chan->rx_state);
6191
6192 if (l2cap_classify_txseq(chan, control->txseq) ==
6193 L2CAP_TXSEQ_EXPECTED) {
6194 l2cap_pass_to_tx(chan, control);
6195
6196 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6197 __next_seq(chan, chan->buffer_seq));
6198
6199 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6200
6201 l2cap_reassemble_sdu(chan, skb, control);
6202 } else {
6203 if (chan->sdu) {
6204 kfree_skb(chan->sdu);
6205 chan->sdu = NULL;
6206 }
6207 chan->sdu_last_frag = NULL;
6208 chan->sdu_len = 0;
6209
6210 if (skb) {
6211 BT_DBG("Freeing %p", skb);
6212 kfree_skb(skb);
6213 }
6214 }
6215
6216 chan->last_acked_seq = control->txseq;
6217 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6218
6219 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006220}
6221
6222static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6223{
6224 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6225 u16 len;
6226 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006227
Mat Martineaub76bbd62012-04-11 10:48:43 -07006228 __unpack_control(chan, skb);
6229
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006230 len = skb->len;
6231
6232 /*
6233 * We can just drop the corrupted I-frame here.
6234 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006235 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006236 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006237 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006238 goto drop;
6239
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006240 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006241 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006242
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006243 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006244 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006245
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006246 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006247 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006248 goto drop;
6249 }
6250
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006251 if (!control->sframe) {
6252 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006253
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006254 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6255 control->sar, control->reqseq, control->final,
6256 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006257
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006258 /* Validate F-bit - F=0 always valid, F=1 only
6259 * valid in TX WAIT_F
6260 */
6261 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006262 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006263
6264 if (chan->mode != L2CAP_MODE_STREAMING) {
6265 event = L2CAP_EV_RECV_IFRAME;
6266 err = l2cap_rx(chan, control, skb, event);
6267 } else {
6268 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006269 }
6270
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006271 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006272 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006273 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006274 const u8 rx_func_to_event[4] = {
6275 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6276 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6277 };
6278
6279 /* Only I-frames are expected in streaming mode */
6280 if (chan->mode == L2CAP_MODE_STREAMING)
6281 goto drop;
6282
6283 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6284 control->reqseq, control->final, control->poll,
6285 control->super);
6286
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006287 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006288 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006289 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006290 goto drop;
6291 }
6292
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006293 /* Validate F and P bits */
6294 if (control->final && (control->poll ||
6295 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6296 goto drop;
6297
6298 event = rx_func_to_event[control->super];
6299 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006300 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006301 }
6302
6303 return 0;
6304
6305drop:
6306 kfree_skb(skb);
6307 return 0;
6308}
6309
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006310static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6311 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006312{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006313 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006314
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006315 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006316 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006317 if (cid == L2CAP_CID_A2MP) {
6318 chan = a2mp_channel_create(conn, skb);
6319 if (!chan) {
6320 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006321 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006322 }
6323
6324 l2cap_chan_lock(chan);
6325 } else {
6326 BT_DBG("unknown cid 0x%4.4x", cid);
6327 /* Drop packet and return */
6328 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006329 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006330 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006331 }
6332
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006333 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006334
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006335 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006336 goto drop;
6337
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006338 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006339 case L2CAP_MODE_BASIC:
6340 /* If socket recv buffers overflows we drop data here
6341 * which is *bad* because L2CAP has to be reliable.
6342 * But we don't have any other choice. L2CAP doesn't
6343 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006344
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006345 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006346 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006347
Gustavo Padovan80b98022012-05-27 22:27:51 -03006348 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006349 goto done;
6350 break;
6351
6352 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006353 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006354 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006355 goto done;
6356
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006357 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006358 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006359 break;
6360 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006361
6362drop:
6363 kfree_skb(skb);
6364
6365done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006366 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006367}
6368
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006369static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6370 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006371{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006372 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006373
Ido Yarivc2287682012-04-20 15:46:07 -03006374 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006375 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006376 goto drop;
6377
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006378 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006379
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006380 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006381 goto drop;
6382
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006383 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006384 goto drop;
6385
Gustavo Padovan80b98022012-05-27 22:27:51 -03006386 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006387 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006388
6389drop:
6390 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006391}
6392
Marcel Holtmann72f78352013-04-23 00:59:00 -07006393static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006394 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006395{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006396 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006397
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006398 chan = l2cap_global_chan_by_scid(0, L2CAP_CID_ATT,
Marcel Holtmann72f78352013-04-23 00:59:00 -07006399 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006400 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006401 goto drop;
6402
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006403 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006404
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006405 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006406 goto drop;
6407
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006408 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006409 goto drop;
6410
Gustavo Padovan80b98022012-05-27 22:27:51 -03006411 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006412 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006413
6414drop:
6415 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006416}
6417
Linus Torvalds1da177e2005-04-16 15:20:36 -07006418static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6419{
6420 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006421 u16 cid, len;
6422 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006423
6424 skb_pull(skb, L2CAP_HDR_SIZE);
6425 cid = __le16_to_cpu(lh->cid);
6426 len = __le16_to_cpu(lh->len);
6427
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006428 if (len != skb->len) {
6429 kfree_skb(skb);
6430 return;
6431 }
6432
Linus Torvalds1da177e2005-04-16 15:20:36 -07006433 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6434
6435 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02006436 case L2CAP_CID_LE_SIGNALING:
Johan Hedbergc5623552013-04-29 19:35:33 +03006437 l2cap_le_sig_channel(conn, skb);
6438 break;
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006439 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006440 l2cap_sig_channel(conn, skb);
6441 break;
6442
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006443 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006444 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006445 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006446 l2cap_conless_channel(conn, psm, skb);
6447 break;
6448
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006449 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006450 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006451 break;
6452
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006453 case L2CAP_CID_SMP:
6454 if (smp_sig_channel(conn, skb))
6455 l2cap_conn_del(conn->hcon, EACCES);
6456 break;
6457
Linus Torvalds1da177e2005-04-16 15:20:36 -07006458 default:
6459 l2cap_data_channel(conn, cid, skb);
6460 break;
6461 }
6462}
6463
6464/* ---- L2CAP interface with lower layer (HCI) ---- */
6465
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006466int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006467{
6468 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006469 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006470
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006471 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006472
6473 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006474 read_lock(&chan_list_lock);
6475 list_for_each_entry(c, &chan_list, global_l) {
6476 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006477
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006478 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006479 continue;
6480
6481 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006482 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006483 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006484 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006485 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006486 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
6487 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006488 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006489 lm2 |= HCI_LM_MASTER;
6490 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006491 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006492 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006493
6494 return exact ? lm1 : lm2;
6495}
6496
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006497void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006498{
Marcel Holtmann01394182006-07-03 10:02:46 +02006499 struct l2cap_conn *conn;
6500
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006501 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006502
Linus Torvalds1da177e2005-04-16 15:20:36 -07006503 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03006504 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006505 if (conn)
6506 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006507 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006508 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006509 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006510}
6511
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006512int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006513{
6514 struct l2cap_conn *conn = hcon->l2cap_data;
6515
6516 BT_DBG("hcon %p", hcon);
6517
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006518 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006519 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006520 return conn->disc_reason;
6521}
6522
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006523void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006524{
6525 BT_DBG("hcon %p reason %d", hcon, reason);
6526
Joe Perchese1750722011-06-29 18:18:29 -07006527 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006528}
6529
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006530static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006531{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006532 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006533 return;
6534
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006535 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006536 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006537 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006538 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006539 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006540 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006541 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006542 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006543 }
6544}
6545
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006546int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006547{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006548 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006549 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006550
Marcel Holtmann01394182006-07-03 10:02:46 +02006551 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006552 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006553
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006554 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006555
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006556 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306557 if (!status && encrypt)
6558 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006559 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006560 }
6561
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006562 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006563
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006564 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006565 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006566
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006567 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6568 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006569
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006570 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6571 l2cap_chan_unlock(chan);
6572 continue;
6573 }
6574
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006575 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006576 if (!status && encrypt) {
6577 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006578 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006579 }
6580
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006581 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006582 continue;
6583 }
6584
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006585 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006586 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006587 continue;
6588 }
6589
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006590 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006591 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03006592 struct sock *sk = chan->sk;
6593
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006594 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03006595 sk->sk_state_change(sk);
6596
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006597 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006598 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006599 continue;
6600 }
6601
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006602 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006603 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006604 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006605 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006606 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006607 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006608 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006609 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006610 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006611 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006612
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006613 lock_sock(sk);
6614
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006615 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006616 if (test_bit(BT_SK_DEFER_SETUP,
6617 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006618 res = L2CAP_CR_PEND;
6619 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006620 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006621 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006622 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006623 res = L2CAP_CR_SUCCESS;
6624 stat = L2CAP_CS_NO_INFO;
6625 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006626 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006627 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006628 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006629 res = L2CAP_CR_SEC_BLOCK;
6630 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006631 }
6632
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006633 release_sock(sk);
6634
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006635 rsp.scid = cpu_to_le16(chan->dcid);
6636 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006637 rsp.result = cpu_to_le16(res);
6638 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006639 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006640 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006641
6642 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6643 res == L2CAP_CR_SUCCESS) {
6644 char buf[128];
6645 set_bit(CONF_REQ_SENT, &chan->conf_state);
6646 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6647 L2CAP_CONF_REQ,
6648 l2cap_build_conf_req(chan, buf),
6649 buf);
6650 chan->num_conf_req++;
6651 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006652 }
6653
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006654 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006655 }
6656
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006657 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006658
Linus Torvalds1da177e2005-04-16 15:20:36 -07006659 return 0;
6660}
6661
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006662int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006663{
6664 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006665 struct l2cap_hdr *hdr;
6666 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006667
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006668 /* For AMP controller do not create l2cap conn */
6669 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6670 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006671
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006672 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03006673 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006674
6675 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006676 goto drop;
6677
6678 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6679
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006680 switch (flags) {
6681 case ACL_START:
6682 case ACL_START_NO_FLUSH:
6683 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006684 if (conn->rx_len) {
6685 BT_ERR("Unexpected start frame (len %d)", skb->len);
6686 kfree_skb(conn->rx_skb);
6687 conn->rx_skb = NULL;
6688 conn->rx_len = 0;
6689 l2cap_conn_unreliable(conn, ECOMM);
6690 }
6691
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006692 /* Start fragment always begin with Basic L2CAP header */
6693 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006694 BT_ERR("Frame is too short (len %d)", skb->len);
6695 l2cap_conn_unreliable(conn, ECOMM);
6696 goto drop;
6697 }
6698
6699 hdr = (struct l2cap_hdr *) skb->data;
6700 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6701
6702 if (len == skb->len) {
6703 /* Complete frame received */
6704 l2cap_recv_frame(conn, skb);
6705 return 0;
6706 }
6707
6708 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6709
6710 if (skb->len > len) {
6711 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006712 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006713 l2cap_conn_unreliable(conn, ECOMM);
6714 goto drop;
6715 }
6716
6717 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006718 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006719 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006720 goto drop;
6721
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006722 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006723 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006724 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006725 break;
6726
6727 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006728 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6729
6730 if (!conn->rx_len) {
6731 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6732 l2cap_conn_unreliable(conn, ECOMM);
6733 goto drop;
6734 }
6735
6736 if (skb->len > conn->rx_len) {
6737 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006738 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006739 kfree_skb(conn->rx_skb);
6740 conn->rx_skb = NULL;
6741 conn->rx_len = 0;
6742 l2cap_conn_unreliable(conn, ECOMM);
6743 goto drop;
6744 }
6745
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006746 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006747 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006748 conn->rx_len -= skb->len;
6749
6750 if (!conn->rx_len) {
6751 /* Complete frame received */
6752 l2cap_recv_frame(conn, conn->rx_skb);
6753 conn->rx_skb = NULL;
6754 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006755 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006756 }
6757
6758drop:
6759 kfree_skb(skb);
6760 return 0;
6761}
6762
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006763static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006764{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006765 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006766
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006767 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006768
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006769 list_for_each_entry(c, &chan_list, global_l) {
6770 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006771
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006772 seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
6773 &bt_sk(sk)->src, &bt_sk(sk)->dst,
6774 c->state, __le16_to_cpu(c->psm),
6775 c->scid, c->dcid, c->imtu, c->omtu,
6776 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006777 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006778
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006779 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006780
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006781 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006782}
6783
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006784static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6785{
6786 return single_open(file, l2cap_debugfs_show, inode->i_private);
6787}
6788
6789static const struct file_operations l2cap_debugfs_fops = {
6790 .open = l2cap_debugfs_open,
6791 .read = seq_read,
6792 .llseek = seq_lseek,
6793 .release = single_release,
6794};
6795
6796static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006797
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006798int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006799{
6800 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006801
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006802 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006803 if (err < 0)
6804 return err;
6805
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006806 if (bt_debugfs) {
Gustavo Padovan2d792812012-10-06 10:07:01 +01006807 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6808 NULL, &l2cap_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006809 if (!l2cap_debugfs)
6810 BT_ERR("Failed to create L2CAP debug file");
6811 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006812
Linus Torvalds1da177e2005-04-16 15:20:36 -07006813 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006814}
6815
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006816void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006817{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006818 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006819 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006820}
6821
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006822module_param(disable_ertm, bool, 0644);
6823MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");