blob: 1557c3c774f1c15870a55ea4b15ac40d86378afb [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{
Johan Hedberg60bac182013-04-29 19:35:41 +03001343 struct sock *parent;
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
Ville Tervob62f3282011-02-10 22:38:50 -03001364 hci_conn_hold(conn->hcon);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001365 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
Ville Tervob62f3282011-02-10 22:38:50 -03001366
Johan Hedberg60bac182013-04-29 19:35:41 +03001367 bacpy(&bt_sk(chan->sk)->src, conn->src);
1368 bacpy(&bt_sk(chan->sk)->dst, conn->dst);
Ville Tervob62f3282011-02-10 22:38:50 -03001369
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001370 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001371
Ville Tervob62f3282011-02-10 22:38:50 -03001372clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001373 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001374}
1375
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001376static void l2cap_conn_ready(struct l2cap_conn *conn)
1377{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001378 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001379 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001380
1381 BT_DBG("conn %p", conn);
1382
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001383 if (!hcon->out && hcon->type == LE_LINK)
Ville Tervob62f3282011-02-10 22:38:50 -03001384 l2cap_le_conn_ready(conn);
1385
Johan Hedbergd8729922013-04-29 19:35:39 +03001386 /* For outgoing pairing which doesn't necessarily have an
1387 * associated socket (e.g. mgmt_pair_device).
1388 */
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001389 if (hcon->out && hcon->type == LE_LINK)
1390 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001391
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001392 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001393
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001394 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001395
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001396 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001397
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001398 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1399 l2cap_chan_unlock(chan);
1400 continue;
1401 }
1402
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001403 if (hcon->type == LE_LINK) {
1404 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001405 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001406
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001407 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001408 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001409 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001410 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001411 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001412 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001413 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001414
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001415 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001416 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001417
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001418 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001419 }
1420
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001421 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001422}
1423
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001424/* Notify sockets that we cannot guaranty reliability anymore */
1425static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1426{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001427 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001428
1429 BT_DBG("conn %p", conn);
1430
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001431 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001432
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001433 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001434 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001435 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001436 }
1437
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001438 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001439}
1440
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001441static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001442{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001443 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001444 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001445
Marcel Holtmann984947d2009-02-06 23:35:19 +01001446 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001447 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001448
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001449 l2cap_conn_start(conn);
1450}
1451
David Herrmann2c8e1412013-04-06 20:28:45 +02001452/*
1453 * l2cap_user
1454 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1455 * callback is called during registration. The ->remove callback is called
1456 * during unregistration.
1457 * An l2cap_user object can either be explicitly unregistered or when the
1458 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1459 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1460 * External modules must own a reference to the l2cap_conn object if they intend
1461 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1462 * any time if they don't.
1463 */
1464
1465int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1466{
1467 struct hci_dev *hdev = conn->hcon->hdev;
1468 int ret;
1469
1470 /* We need to check whether l2cap_conn is registered. If it is not, we
1471 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1472 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1473 * relies on the parent hci_conn object to be locked. This itself relies
1474 * on the hci_dev object to be locked. So we must lock the hci device
1475 * here, too. */
1476
1477 hci_dev_lock(hdev);
1478
1479 if (user->list.next || user->list.prev) {
1480 ret = -EINVAL;
1481 goto out_unlock;
1482 }
1483
1484 /* conn->hchan is NULL after l2cap_conn_del() was called */
1485 if (!conn->hchan) {
1486 ret = -ENODEV;
1487 goto out_unlock;
1488 }
1489
1490 ret = user->probe(conn, user);
1491 if (ret)
1492 goto out_unlock;
1493
1494 list_add(&user->list, &conn->users);
1495 ret = 0;
1496
1497out_unlock:
1498 hci_dev_unlock(hdev);
1499 return ret;
1500}
1501EXPORT_SYMBOL(l2cap_register_user);
1502
1503void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1504{
1505 struct hci_dev *hdev = conn->hcon->hdev;
1506
1507 hci_dev_lock(hdev);
1508
1509 if (!user->list.next || !user->list.prev)
1510 goto out_unlock;
1511
1512 list_del(&user->list);
1513 user->list.next = NULL;
1514 user->list.prev = NULL;
1515 user->remove(conn, user);
1516
1517out_unlock:
1518 hci_dev_unlock(hdev);
1519}
1520EXPORT_SYMBOL(l2cap_unregister_user);
1521
1522static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1523{
1524 struct l2cap_user *user;
1525
1526 while (!list_empty(&conn->users)) {
1527 user = list_first_entry(&conn->users, struct l2cap_user, list);
1528 list_del(&user->list);
1529 user->list.next = NULL;
1530 user->list.prev = NULL;
1531 user->remove(conn, user);
1532 }
1533}
1534
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001535static void l2cap_conn_del(struct hci_conn *hcon, int err)
1536{
1537 struct l2cap_conn *conn = hcon->l2cap_data;
1538 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001539
1540 if (!conn)
1541 return;
1542
1543 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1544
1545 kfree_skb(conn->rx_skb);
1546
David Herrmann2c8e1412013-04-06 20:28:45 +02001547 l2cap_unregister_all_users(conn);
1548
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001549 mutex_lock(&conn->chan_lock);
1550
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001551 /* Kill channels */
1552 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001553 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001554 l2cap_chan_lock(chan);
1555
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001556 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001557
1558 l2cap_chan_unlock(chan);
1559
Gustavo Padovan80b98022012-05-27 22:27:51 -03001560 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001561 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001562 }
1563
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001564 mutex_unlock(&conn->chan_lock);
1565
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001566 hci_chan_del(conn->hchan);
1567
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001568 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001569 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001570
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001571 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001572 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001573 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001574 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001575
1576 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001577 conn->hchan = NULL;
1578 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001579}
1580
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001581static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001582{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001583 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001584 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001585
Johan Hedbergd06cc412012-06-06 18:44:11 +08001586 BT_DBG("conn %p", conn);
1587
1588 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1589 smp_chan_destroy(conn);
1590 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1591 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001592}
1593
Claudio Takahasibaf43252013-04-11 13:55:50 -03001594static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595{
Marcel Holtmann01394182006-07-03 10:02:46 +02001596 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001597 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598
Claudio Takahasibaf43252013-04-11 13:55:50 -03001599 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600 return conn;
1601
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001602 hchan = hci_chan_create(hcon);
1603 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001606 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001607 if (!conn) {
1608 hci_chan_del(hchan);
1609 return NULL;
1610 }
1611
David Herrmann9c903e32013-04-06 20:28:44 +02001612 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613 hcon->l2cap_data = conn;
1614 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001615 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001616 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001618 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001619
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001620 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001621 case LE_LINK:
1622 if (hcon->hdev->le_mtu) {
1623 conn->mtu = hcon->hdev->le_mtu;
1624 break;
1625 }
1626 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001627 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001628 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001629 break;
1630 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001631
Linus Torvalds1da177e2005-04-16 15:20:36 -07001632 conn->src = &hcon->hdev->bdaddr;
1633 conn->dst = &hcon->dst;
1634
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001635 conn->feat_mask = 0;
1636
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001638 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001639
1640 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001641 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001643 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001644 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001645 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001646 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001647
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001648 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001649
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650 return conn;
1651}
1652
David Herrmann9c903e32013-04-06 20:28:44 +02001653static void l2cap_conn_free(struct kref *ref)
1654{
1655 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1656
1657 hci_conn_put(conn->hcon);
1658 kfree(conn);
1659}
1660
1661void l2cap_conn_get(struct l2cap_conn *conn)
1662{
1663 kref_get(&conn->ref);
1664}
1665EXPORT_SYMBOL(l2cap_conn_get);
1666
1667void l2cap_conn_put(struct l2cap_conn *conn)
1668{
1669 kref_put(&conn->ref, l2cap_conn_free);
1670}
1671EXPORT_SYMBOL(l2cap_conn_put);
1672
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674
Ido Yarivc2287682012-04-20 15:46:07 -03001675/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676 * Returns closest match.
1677 */
Ido Yarivc2287682012-04-20 15:46:07 -03001678static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1679 bdaddr_t *src,
1680 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001682 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001684 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001685
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001686 list_for_each_entry(c, &chan_list, global_l) {
1687 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001688
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001689 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690 continue;
1691
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001692 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001693 int src_match, dst_match;
1694 int src_any, dst_any;
1695
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001697 src_match = !bacmp(&bt_sk(sk)->src, src);
1698 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1699 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001700 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001701 return c;
1702 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703
1704 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001705 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1706 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1707 if ((src_match && dst_any) || (src_any && dst_match) ||
1708 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001709 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710 }
1711 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001713 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001714
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001715 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716}
1717
Andre Guedes8e9f9892012-04-24 21:02:55 -03001718int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1719 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001721 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 struct l2cap_conn *conn;
1724 struct hci_conn *hcon;
1725 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001726 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001727 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001728
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001729 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301730 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001732 hdev = hci_get_route(dst, src);
1733 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734 return -EHOSTUNREACH;
1735
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001736 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001738 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001739
1740 /* PSM must be odd and lsb of upper byte must be 0 */
1741 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001742 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001743 err = -EINVAL;
1744 goto done;
1745 }
1746
1747 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1748 err = -EINVAL;
1749 goto done;
1750 }
1751
1752 switch (chan->mode) {
1753 case L2CAP_MODE_BASIC:
1754 break;
1755 case L2CAP_MODE_ERTM:
1756 case L2CAP_MODE_STREAMING:
1757 if (!disable_ertm)
1758 break;
1759 /* fall through */
1760 default:
1761 err = -ENOTSUPP;
1762 goto done;
1763 }
1764
Gustavo Padovan0797e012012-05-27 22:27:54 -03001765 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001766 case BT_CONNECT:
1767 case BT_CONNECT2:
1768 case BT_CONFIG:
1769 /* Already connecting */
1770 err = 0;
1771 goto done;
1772
1773 case BT_CONNECTED:
1774 /* Already connected */
1775 err = -EISCONN;
1776 goto done;
1777
1778 case BT_OPEN:
1779 case BT_BOUND:
1780 /* Can connect */
1781 break;
1782
1783 default:
1784 err = -EBADFD;
1785 goto done;
1786 }
1787
1788 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001789 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001790 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001791 release_sock(sk);
1792
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001793 chan->psm = psm;
1794 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001796 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001797
Johan Hedbergf224ca52013-04-29 19:35:36 +03001798 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001799 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001800 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001801 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001802 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001803 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001804
Ville Tervo30e76272011-02-22 16:10:53 -03001805 if (IS_ERR(hcon)) {
1806 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001808 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809
Claudio Takahasibaf43252013-04-11 13:55:50 -03001810 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001812 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001813 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 goto done;
1815 }
1816
Johan Hedberg141d5702013-04-29 19:35:37 +03001817 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1818 hci_conn_drop(hcon);
1819 err = -EBUSY;
1820 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001821 }
1822
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823 /* Update source addr of the socket */
1824 bacpy(src, conn->src);
1825
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001826 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001827 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001828 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001829
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001830 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001831 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832
1833 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001834 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001835 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001836 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001837 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001838 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001839 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840 }
1841
Ville Tervo30e76272011-02-22 16:10:53 -03001842 err = 0;
1843
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001845 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001846 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847 hci_dev_put(hdev);
1848 return err;
1849}
1850
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001851int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001852{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001853 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001854 DECLARE_WAITQUEUE(wait, current);
1855 int err = 0;
1856 int timeo = HZ/5;
1857
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001858 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001859 set_current_state(TASK_INTERRUPTIBLE);
1860 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001861 if (!timeo)
1862 timeo = HZ/5;
1863
1864 if (signal_pending(current)) {
1865 err = sock_intr_errno(timeo);
1866 break;
1867 }
1868
1869 release_sock(sk);
1870 timeo = schedule_timeout(timeo);
1871 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001872 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001873
1874 err = sock_error(sk);
1875 if (err)
1876 break;
1877 }
1878 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001879 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001880 return err;
1881}
1882
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001883static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001884{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001885 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001886 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001887
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001888 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001889
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001890 l2cap_chan_lock(chan);
1891
Mat Martineau80909e02012-05-17 20:53:50 -07001892 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001893 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001894 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001895 return;
1896 }
1897
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001898 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001899
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001900 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001901 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001902}
1903
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001904static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001905{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001906 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001907 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001908
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001909 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001910
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001911 l2cap_chan_lock(chan);
1912
Mat Martineau80909e02012-05-17 20:53:50 -07001913 if (!chan->conn) {
1914 l2cap_chan_unlock(chan);
1915 l2cap_chan_put(chan);
1916 return;
1917 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001918
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001919 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001920 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001921 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001922}
1923
Gustavo Padovand6603662012-05-21 13:58:22 -03001924static void l2cap_streaming_send(struct l2cap_chan *chan,
1925 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001926{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001927 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001928 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001929
Mat Martineau37339372012-05-17 20:53:33 -07001930 BT_DBG("chan %p, skbs %p", chan, skbs);
1931
Mat Martineaub99e13a2012-10-23 15:24:19 -07001932 if (__chan_is_moving(chan))
1933 return;
1934
Mat Martineau37339372012-05-17 20:53:33 -07001935 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1936
1937 while (!skb_queue_empty(&chan->tx_q)) {
1938
1939 skb = skb_dequeue(&chan->tx_q);
1940
1941 bt_cb(skb)->control.retries = 1;
1942 control = &bt_cb(skb)->control;
1943
1944 control->reqseq = 0;
1945 control->txseq = chan->next_tx_seq;
1946
1947 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001948
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001949 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001950 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1951 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001952 }
1953
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001954 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001955
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001956 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001957
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001958 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001959 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001960 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001961}
1962
Szymon Janc67c9e842011-07-28 16:24:33 +02001963static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001964{
1965 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001966 struct l2cap_ctrl *control;
1967 int sent = 0;
1968
1969 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001970
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001971 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001972 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001973
Mat Martineau94122bb2012-05-02 09:42:02 -07001974 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1975 return 0;
1976
Mat Martineaub99e13a2012-10-23 15:24:19 -07001977 if (__chan_is_moving(chan))
1978 return 0;
1979
Mat Martineau18a48e72012-05-17 20:53:34 -07001980 while (chan->tx_send_head &&
1981 chan->unacked_frames < chan->remote_tx_win &&
1982 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001983
Mat Martineau18a48e72012-05-17 20:53:34 -07001984 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001985
Mat Martineau18a48e72012-05-17 20:53:34 -07001986 bt_cb(skb)->control.retries = 1;
1987 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001988
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001989 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001990 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001991
Mat Martineau18a48e72012-05-17 20:53:34 -07001992 control->reqseq = chan->buffer_seq;
1993 chan->last_acked_seq = chan->buffer_seq;
1994 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001995
Mat Martineau18a48e72012-05-17 20:53:34 -07001996 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001997
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001998 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001999 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2000 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002001 }
2002
Mat Martineau18a48e72012-05-17 20:53:34 -07002003 /* Clone after data has been modified. Data is assumed to be
2004 read-only (for locking purposes) on cloned sk_buffs.
2005 */
2006 tx_skb = skb_clone(skb, GFP_KERNEL);
2007
2008 if (!tx_skb)
2009 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002010
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002011 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002012
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002013 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002014 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002015 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002016 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002017
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002018 if (skb_queue_is_last(&chan->tx_q, skb))
2019 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002020 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002021 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002022
2023 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002024 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002025 }
2026
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002027 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2028 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002029
2030 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002031}
2032
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002033static void l2cap_ertm_resend(struct l2cap_chan *chan)
2034{
2035 struct l2cap_ctrl control;
2036 struct sk_buff *skb;
2037 struct sk_buff *tx_skb;
2038 u16 seq;
2039
2040 BT_DBG("chan %p", chan);
2041
2042 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2043 return;
2044
Mat Martineaub99e13a2012-10-23 15:24:19 -07002045 if (__chan_is_moving(chan))
2046 return;
2047
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002048 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2049 seq = l2cap_seq_list_pop(&chan->retrans_list);
2050
2051 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2052 if (!skb) {
2053 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002054 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002055 continue;
2056 }
2057
2058 bt_cb(skb)->control.retries++;
2059 control = bt_cb(skb)->control;
2060
2061 if (chan->max_tx != 0 &&
2062 bt_cb(skb)->control.retries > chan->max_tx) {
2063 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002064 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002065 l2cap_seq_list_clear(&chan->retrans_list);
2066 break;
2067 }
2068
2069 control.reqseq = chan->buffer_seq;
2070 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2071 control.final = 1;
2072 else
2073 control.final = 0;
2074
2075 if (skb_cloned(skb)) {
2076 /* Cloned sk_buffs are read-only, so we need a
2077 * writeable copy
2078 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002079 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002080 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002081 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002082 }
2083
2084 if (!tx_skb) {
2085 l2cap_seq_list_clear(&chan->retrans_list);
2086 break;
2087 }
2088
2089 /* Update skb contents */
2090 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2091 put_unaligned_le32(__pack_extended_control(&control),
2092 tx_skb->data + L2CAP_HDR_SIZE);
2093 } else {
2094 put_unaligned_le16(__pack_enhanced_control(&control),
2095 tx_skb->data + L2CAP_HDR_SIZE);
2096 }
2097
2098 if (chan->fcs == L2CAP_FCS_CRC16) {
2099 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2100 put_unaligned_le16(fcs, skb_put(tx_skb,
2101 L2CAP_FCS_SIZE));
2102 }
2103
2104 l2cap_do_send(chan, tx_skb);
2105
2106 BT_DBG("Resent txseq %d", control.txseq);
2107
2108 chan->last_acked_seq = chan->buffer_seq;
2109 }
2110}
2111
Mat Martineauf80842a2012-05-17 20:53:46 -07002112static void l2cap_retransmit(struct l2cap_chan *chan,
2113 struct l2cap_ctrl *control)
2114{
2115 BT_DBG("chan %p, control %p", chan, control);
2116
2117 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2118 l2cap_ertm_resend(chan);
2119}
2120
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002121static void l2cap_retransmit_all(struct l2cap_chan *chan,
2122 struct l2cap_ctrl *control)
2123{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002124 struct sk_buff *skb;
2125
2126 BT_DBG("chan %p, control %p", chan, control);
2127
2128 if (control->poll)
2129 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2130
2131 l2cap_seq_list_clear(&chan->retrans_list);
2132
2133 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2134 return;
2135
2136 if (chan->unacked_frames) {
2137 skb_queue_walk(&chan->tx_q, skb) {
2138 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002139 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002140 break;
2141 }
2142
2143 skb_queue_walk_from(&chan->tx_q, skb) {
2144 if (skb == chan->tx_send_head)
2145 break;
2146
2147 l2cap_seq_list_append(&chan->retrans_list,
2148 bt_cb(skb)->control.txseq);
2149 }
2150
2151 l2cap_ertm_resend(chan);
2152 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002153}
2154
Szymon Jancb17e73b2012-01-11 10:59:47 +01002155static void l2cap_send_ack(struct l2cap_chan *chan)
2156{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002157 struct l2cap_ctrl control;
2158 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2159 chan->last_acked_seq);
2160 int threshold;
2161
2162 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2163 chan, chan->last_acked_seq, chan->buffer_seq);
2164
2165 memset(&control, 0, sizeof(control));
2166 control.sframe = 1;
2167
2168 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2169 chan->rx_state == L2CAP_RX_STATE_RECV) {
2170 __clear_ack_timer(chan);
2171 control.super = L2CAP_SUPER_RNR;
2172 control.reqseq = chan->buffer_seq;
2173 l2cap_send_sframe(chan, &control);
2174 } else {
2175 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2176 l2cap_ertm_send(chan);
2177 /* If any i-frames were sent, they included an ack */
2178 if (chan->buffer_seq == chan->last_acked_seq)
2179 frames_to_ack = 0;
2180 }
2181
Mat Martineauc20f8e32012-07-10 05:47:07 -07002182 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002183 * Calculate without mul or div
2184 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002185 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002186 threshold += threshold << 1;
2187 threshold >>= 2;
2188
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002189 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002190 threshold);
2191
2192 if (frames_to_ack >= threshold) {
2193 __clear_ack_timer(chan);
2194 control.super = L2CAP_SUPER_RR;
2195 control.reqseq = chan->buffer_seq;
2196 l2cap_send_sframe(chan, &control);
2197 frames_to_ack = 0;
2198 }
2199
2200 if (frames_to_ack)
2201 __set_ack_timer(chan);
2202 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002203}
2204
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002205static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2206 struct msghdr *msg, int len,
2207 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002208{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002209 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002210 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002211 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002212
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002213 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002214 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002215
2216 sent += count;
2217 len -= count;
2218
2219 /* Continuation fragments (no L2CAP header) */
2220 frag = &skb_shinfo(skb)->frag_list;
2221 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002222 struct sk_buff *tmp;
2223
Linus Torvalds1da177e2005-04-16 15:20:36 -07002224 count = min_t(unsigned int, conn->mtu, len);
2225
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002226 tmp = chan->ops->alloc_skb(chan, count,
2227 msg->msg_flags & MSG_DONTWAIT);
2228 if (IS_ERR(tmp))
2229 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002230
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002231 *frag = tmp;
2232
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002233 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2234 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002235
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002236 (*frag)->priority = skb->priority;
2237
Linus Torvalds1da177e2005-04-16 15:20:36 -07002238 sent += count;
2239 len -= count;
2240
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002241 skb->len += (*frag)->len;
2242 skb->data_len += (*frag)->len;
2243
Linus Torvalds1da177e2005-04-16 15:20:36 -07002244 frag = &(*frag)->next;
2245 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002246
2247 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002248}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002250static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002251 struct msghdr *msg, size_t len,
2252 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002253{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002254 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002255 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002256 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002257 struct l2cap_hdr *lh;
2258
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002259 BT_DBG("chan %p len %zu priority %u", chan, len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002260
2261 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002262
2263 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002264 msg->msg_flags & MSG_DONTWAIT);
2265 if (IS_ERR(skb))
2266 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002267
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002268 skb->priority = priority;
2269
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002270 /* Create L2CAP header */
2271 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002272 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002273 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
2274 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002275
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002276 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002277 if (unlikely(err < 0)) {
2278 kfree_skb(skb);
2279 return ERR_PTR(err);
2280 }
2281 return skb;
2282}
2283
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002284static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002285 struct msghdr *msg, size_t len,
2286 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002287{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002288 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002289 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002290 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002291 struct l2cap_hdr *lh;
2292
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002293 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002294
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002295 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002296
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002297 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002298 msg->msg_flags & MSG_DONTWAIT);
2299 if (IS_ERR(skb))
2300 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002301
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002302 skb->priority = priority;
2303
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002304 /* Create L2CAP header */
2305 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002306 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002307 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002308
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002309 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002310 if (unlikely(err < 0)) {
2311 kfree_skb(skb);
2312 return ERR_PTR(err);
2313 }
2314 return skb;
2315}
2316
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002317static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002318 struct msghdr *msg, size_t len,
2319 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002320{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002321 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002322 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002323 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002324 struct l2cap_hdr *lh;
2325
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002326 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002327
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002328 if (!conn)
2329 return ERR_PTR(-ENOTCONN);
2330
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002331 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002332
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002333 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002334 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002335
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002336 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002337 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002338
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002339 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002340
2341 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002342 msg->msg_flags & MSG_DONTWAIT);
2343 if (IS_ERR(skb))
2344 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002345
2346 /* Create L2CAP header */
2347 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002348 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002349 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002350
Mat Martineau18a48e72012-05-17 20:53:34 -07002351 /* Control header is populated later */
2352 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2353 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2354 else
2355 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002356
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002357 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002358 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002359
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002360 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002361 if (unlikely(err < 0)) {
2362 kfree_skb(skb);
2363 return ERR_PTR(err);
2364 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002365
Mat Martineau18a48e72012-05-17 20:53:34 -07002366 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002367 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002368 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002369}
2370
Mat Martineau94122bb2012-05-02 09:42:02 -07002371static int l2cap_segment_sdu(struct l2cap_chan *chan,
2372 struct sk_buff_head *seg_queue,
2373 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002374{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002375 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002376 u16 sdu_len;
2377 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002378 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002379
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002380 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002381
Mat Martineau94122bb2012-05-02 09:42:02 -07002382 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2383 * so fragmented skbs are not used. The HCI layer's handling
2384 * of fragmented skbs is not compatible with ERTM's queueing.
2385 */
2386
2387 /* PDU size is derived from the HCI MTU */
2388 pdu_len = chan->conn->mtu;
2389
Mat Martineaua5495742012-10-23 15:24:21 -07002390 /* Constrain PDU size for BR/EDR connections */
2391 if (!chan->hs_hcon)
2392 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002393
2394 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002395 if (chan->fcs)
2396 pdu_len -= L2CAP_FCS_SIZE;
2397
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002398 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002399
2400 /* Remote device may have requested smaller PDUs */
2401 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2402
2403 if (len <= pdu_len) {
2404 sar = L2CAP_SAR_UNSEGMENTED;
2405 sdu_len = 0;
2406 pdu_len = len;
2407 } else {
2408 sar = L2CAP_SAR_START;
2409 sdu_len = len;
2410 pdu_len -= L2CAP_SDULEN_SIZE;
2411 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002412
2413 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002414 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002415
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002416 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002417 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002418 return PTR_ERR(skb);
2419 }
2420
Mat Martineau94122bb2012-05-02 09:42:02 -07002421 bt_cb(skb)->control.sar = sar;
2422 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002423
Mat Martineau94122bb2012-05-02 09:42:02 -07002424 len -= pdu_len;
2425 if (sdu_len) {
2426 sdu_len = 0;
2427 pdu_len += L2CAP_SDULEN_SIZE;
2428 }
2429
2430 if (len <= pdu_len) {
2431 sar = L2CAP_SAR_END;
2432 pdu_len = len;
2433 } else {
2434 sar = L2CAP_SAR_CONTINUE;
2435 }
2436 }
2437
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002438 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002439}
2440
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002441int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002442 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002443{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002444 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002445 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002446 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002447
2448 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002449 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002450 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002451 if (IS_ERR(skb))
2452 return PTR_ERR(skb);
2453
2454 l2cap_do_send(chan, skb);
2455 return len;
2456 }
2457
2458 switch (chan->mode) {
2459 case L2CAP_MODE_BASIC:
2460 /* Check outgoing MTU */
2461 if (len > chan->omtu)
2462 return -EMSGSIZE;
2463
2464 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002465 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002466 if (IS_ERR(skb))
2467 return PTR_ERR(skb);
2468
2469 l2cap_do_send(chan, skb);
2470 err = len;
2471 break;
2472
2473 case L2CAP_MODE_ERTM:
2474 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002475 /* Check outgoing MTU */
2476 if (len > chan->omtu) {
2477 err = -EMSGSIZE;
2478 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002479 }
2480
Mat Martineau94122bb2012-05-02 09:42:02 -07002481 __skb_queue_head_init(&seg_queue);
2482
2483 /* Do segmentation before calling in to the state machine,
2484 * since it's possible to block while waiting for memory
2485 * allocation.
2486 */
2487 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2488
2489 /* The channel could have been closed while segmenting,
2490 * check that it is still connected.
2491 */
2492 if (chan->state != BT_CONNECTED) {
2493 __skb_queue_purge(&seg_queue);
2494 err = -ENOTCONN;
2495 }
2496
2497 if (err)
2498 break;
2499
Mat Martineau37339372012-05-17 20:53:33 -07002500 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002501 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002502 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002503 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002504
Gustavo Padovand6603662012-05-21 13:58:22 -03002505 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002506
Mat Martineau94122bb2012-05-02 09:42:02 -07002507 /* If the skbs were not queued for sending, they'll still be in
2508 * seg_queue and need to be purged.
2509 */
2510 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002511 break;
2512
2513 default:
2514 BT_DBG("bad state %1.1x", chan->mode);
2515 err = -EBADFD;
2516 }
2517
2518 return err;
2519}
2520
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002521static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2522{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002523 struct l2cap_ctrl control;
2524 u16 seq;
2525
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002526 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002527
2528 memset(&control, 0, sizeof(control));
2529 control.sframe = 1;
2530 control.super = L2CAP_SUPER_SREJ;
2531
2532 for (seq = chan->expected_tx_seq; seq != txseq;
2533 seq = __next_seq(chan, seq)) {
2534 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2535 control.reqseq = seq;
2536 l2cap_send_sframe(chan, &control);
2537 l2cap_seq_list_append(&chan->srej_list, seq);
2538 }
2539 }
2540
2541 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002542}
2543
2544static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2545{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002546 struct l2cap_ctrl control;
2547
2548 BT_DBG("chan %p", chan);
2549
2550 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2551 return;
2552
2553 memset(&control, 0, sizeof(control));
2554 control.sframe = 1;
2555 control.super = L2CAP_SUPER_SREJ;
2556 control.reqseq = chan->srej_list.tail;
2557 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002558}
2559
2560static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2561{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002562 struct l2cap_ctrl control;
2563 u16 initial_head;
2564 u16 seq;
2565
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002566 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002567
2568 memset(&control, 0, sizeof(control));
2569 control.sframe = 1;
2570 control.super = L2CAP_SUPER_SREJ;
2571
2572 /* Capture initial list head to allow only one pass through the list. */
2573 initial_head = chan->srej_list.head;
2574
2575 do {
2576 seq = l2cap_seq_list_pop(&chan->srej_list);
2577 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2578 break;
2579
2580 control.reqseq = seq;
2581 l2cap_send_sframe(chan, &control);
2582 l2cap_seq_list_append(&chan->srej_list, seq);
2583 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002584}
2585
Mat Martineau608bcc62012-05-17 20:53:32 -07002586static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2587{
2588 struct sk_buff *acked_skb;
2589 u16 ackseq;
2590
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002591 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002592
2593 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2594 return;
2595
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002596 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002597 chan->expected_ack_seq, chan->unacked_frames);
2598
2599 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2600 ackseq = __next_seq(chan, ackseq)) {
2601
2602 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2603 if (acked_skb) {
2604 skb_unlink(acked_skb, &chan->tx_q);
2605 kfree_skb(acked_skb);
2606 chan->unacked_frames--;
2607 }
2608 }
2609
2610 chan->expected_ack_seq = reqseq;
2611
2612 if (chan->unacked_frames == 0)
2613 __clear_retrans_timer(chan);
2614
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002615 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002616}
2617
2618static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2619{
2620 BT_DBG("chan %p", chan);
2621
2622 chan->expected_tx_seq = chan->buffer_seq;
2623 l2cap_seq_list_clear(&chan->srej_list);
2624 skb_queue_purge(&chan->srej_q);
2625 chan->rx_state = L2CAP_RX_STATE_RECV;
2626}
2627
Gustavo Padovand6603662012-05-21 13:58:22 -03002628static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2629 struct l2cap_ctrl *control,
2630 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002631{
Mat Martineau608bcc62012-05-17 20:53:32 -07002632 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2633 event);
2634
2635 switch (event) {
2636 case L2CAP_EV_DATA_REQUEST:
2637 if (chan->tx_send_head == NULL)
2638 chan->tx_send_head = skb_peek(skbs);
2639
2640 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2641 l2cap_ertm_send(chan);
2642 break;
2643 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2644 BT_DBG("Enter LOCAL_BUSY");
2645 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2646
2647 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2648 /* The SREJ_SENT state must be aborted if we are to
2649 * enter the LOCAL_BUSY state.
2650 */
2651 l2cap_abort_rx_srej_sent(chan);
2652 }
2653
2654 l2cap_send_ack(chan);
2655
2656 break;
2657 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2658 BT_DBG("Exit LOCAL_BUSY");
2659 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2660
2661 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2662 struct l2cap_ctrl local_control;
2663
2664 memset(&local_control, 0, sizeof(local_control));
2665 local_control.sframe = 1;
2666 local_control.super = L2CAP_SUPER_RR;
2667 local_control.poll = 1;
2668 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002669 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002670
2671 chan->retry_count = 1;
2672 __set_monitor_timer(chan);
2673 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2674 }
2675 break;
2676 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2677 l2cap_process_reqseq(chan, control->reqseq);
2678 break;
2679 case L2CAP_EV_EXPLICIT_POLL:
2680 l2cap_send_rr_or_rnr(chan, 1);
2681 chan->retry_count = 1;
2682 __set_monitor_timer(chan);
2683 __clear_ack_timer(chan);
2684 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2685 break;
2686 case L2CAP_EV_RETRANS_TO:
2687 l2cap_send_rr_or_rnr(chan, 1);
2688 chan->retry_count = 1;
2689 __set_monitor_timer(chan);
2690 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2691 break;
2692 case L2CAP_EV_RECV_FBIT:
2693 /* Nothing to process */
2694 break;
2695 default:
2696 break;
2697 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002698}
2699
Gustavo Padovand6603662012-05-21 13:58:22 -03002700static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2701 struct l2cap_ctrl *control,
2702 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002703{
Mat Martineau608bcc62012-05-17 20:53:32 -07002704 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2705 event);
2706
2707 switch (event) {
2708 case L2CAP_EV_DATA_REQUEST:
2709 if (chan->tx_send_head == NULL)
2710 chan->tx_send_head = skb_peek(skbs);
2711 /* Queue data, but don't send. */
2712 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2713 break;
2714 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2715 BT_DBG("Enter LOCAL_BUSY");
2716 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2717
2718 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2719 /* The SREJ_SENT state must be aborted if we are to
2720 * enter the LOCAL_BUSY state.
2721 */
2722 l2cap_abort_rx_srej_sent(chan);
2723 }
2724
2725 l2cap_send_ack(chan);
2726
2727 break;
2728 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2729 BT_DBG("Exit LOCAL_BUSY");
2730 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2731
2732 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2733 struct l2cap_ctrl local_control;
2734 memset(&local_control, 0, sizeof(local_control));
2735 local_control.sframe = 1;
2736 local_control.super = L2CAP_SUPER_RR;
2737 local_control.poll = 1;
2738 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002739 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002740
2741 chan->retry_count = 1;
2742 __set_monitor_timer(chan);
2743 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2744 }
2745 break;
2746 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2747 l2cap_process_reqseq(chan, control->reqseq);
2748
2749 /* Fall through */
2750
2751 case L2CAP_EV_RECV_FBIT:
2752 if (control && control->final) {
2753 __clear_monitor_timer(chan);
2754 if (chan->unacked_frames > 0)
2755 __set_retrans_timer(chan);
2756 chan->retry_count = 0;
2757 chan->tx_state = L2CAP_TX_STATE_XMIT;
2758 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2759 }
2760 break;
2761 case L2CAP_EV_EXPLICIT_POLL:
2762 /* Ignore */
2763 break;
2764 case L2CAP_EV_MONITOR_TO:
2765 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2766 l2cap_send_rr_or_rnr(chan, 1);
2767 __set_monitor_timer(chan);
2768 chan->retry_count++;
2769 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002770 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002771 }
2772 break;
2773 default:
2774 break;
2775 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002776}
2777
Gustavo Padovand6603662012-05-21 13:58:22 -03002778static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2779 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002780{
Mat Martineau608bcc62012-05-17 20:53:32 -07002781 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2782 chan, control, skbs, event, chan->tx_state);
2783
2784 switch (chan->tx_state) {
2785 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002786 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002787 break;
2788 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002789 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002790 break;
2791 default:
2792 /* Ignore event */
2793 break;
2794 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002795}
2796
Mat Martineau4b51dae92012-05-17 20:53:37 -07002797static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2798 struct l2cap_ctrl *control)
2799{
2800 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002801 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002802}
2803
Mat Martineauf80842a2012-05-17 20:53:46 -07002804static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2805 struct l2cap_ctrl *control)
2806{
2807 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002808 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002809}
2810
Linus Torvalds1da177e2005-04-16 15:20:36 -07002811/* Copy frame to all raw sockets on that connection */
2812static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2813{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002814 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002815 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002816
2817 BT_DBG("conn %p", conn);
2818
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002819 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002820
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002821 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002822 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002823 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002824 continue;
2825
2826 /* Don't send frame to the socket it came from */
2827 if (skb->sk == sk)
2828 continue;
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002829 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002830 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002831 continue;
2832
Gustavo Padovan80b98022012-05-27 22:27:51 -03002833 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002834 kfree_skb(nskb);
2835 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002836
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002837 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002838}
2839
2840/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002841static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2842 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002843{
2844 struct sk_buff *skb, **frag;
2845 struct l2cap_cmd_hdr *cmd;
2846 struct l2cap_hdr *lh;
2847 int len, count;
2848
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002849 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2850 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002851
Anderson Lizardo300b9622013-06-02 16:30:40 -04002852 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2853 return NULL;
2854
Linus Torvalds1da177e2005-04-16 15:20:36 -07002855 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2856 count = min_t(unsigned int, conn->mtu, len);
2857
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002858 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002859 if (!skb)
2860 return NULL;
2861
2862 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002863 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002864
2865 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002866 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002867 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002868 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002869
2870 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2871 cmd->code = code;
2872 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002873 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002874
2875 if (dlen) {
2876 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2877 memcpy(skb_put(skb, count), data, count);
2878 data += count;
2879 }
2880
2881 len -= skb->len;
2882
2883 /* Continuation fragments (no L2CAP header) */
2884 frag = &skb_shinfo(skb)->frag_list;
2885 while (len) {
2886 count = min_t(unsigned int, conn->mtu, len);
2887
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002888 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002889 if (!*frag)
2890 goto fail;
2891
2892 memcpy(skb_put(*frag, count), data, count);
2893
2894 len -= count;
2895 data += count;
2896
2897 frag = &(*frag)->next;
2898 }
2899
2900 return skb;
2901
2902fail:
2903 kfree_skb(skb);
2904 return NULL;
2905}
2906
Gustavo Padovan2d792812012-10-06 10:07:01 +01002907static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2908 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002909{
2910 struct l2cap_conf_opt *opt = *ptr;
2911 int len;
2912
2913 len = L2CAP_CONF_OPT_SIZE + opt->len;
2914 *ptr += len;
2915
2916 *type = opt->type;
2917 *olen = opt->len;
2918
2919 switch (opt->len) {
2920 case 1:
2921 *val = *((u8 *) opt->val);
2922 break;
2923
2924 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002925 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002926 break;
2927
2928 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002929 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002930 break;
2931
2932 default:
2933 *val = (unsigned long) opt->val;
2934 break;
2935 }
2936
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002937 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002938 return len;
2939}
2940
Linus Torvalds1da177e2005-04-16 15:20:36 -07002941static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2942{
2943 struct l2cap_conf_opt *opt = *ptr;
2944
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002945 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002946
2947 opt->type = type;
2948 opt->len = len;
2949
2950 switch (len) {
2951 case 1:
2952 *((u8 *) opt->val) = val;
2953 break;
2954
2955 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002956 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002957 break;
2958
2959 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002960 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002961 break;
2962
2963 default:
2964 memcpy(opt->val, (void *) val, len);
2965 break;
2966 }
2967
2968 *ptr += L2CAP_CONF_OPT_SIZE + len;
2969}
2970
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002971static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2972{
2973 struct l2cap_conf_efs efs;
2974
Szymon Janc1ec918c2011-11-16 09:32:21 +01002975 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002976 case L2CAP_MODE_ERTM:
2977 efs.id = chan->local_id;
2978 efs.stype = chan->local_stype;
2979 efs.msdu = cpu_to_le16(chan->local_msdu);
2980 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002981 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002982 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002983 break;
2984
2985 case L2CAP_MODE_STREAMING:
2986 efs.id = 1;
2987 efs.stype = L2CAP_SERV_BESTEFFORT;
2988 efs.msdu = cpu_to_le16(chan->local_msdu);
2989 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2990 efs.acc_lat = 0;
2991 efs.flush_to = 0;
2992 break;
2993
2994 default:
2995 return;
2996 }
2997
2998 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002999 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003000}
3001
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003002static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003003{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003004 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003005 ack_timer.work);
3006 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003007
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003008 BT_DBG("chan %p", chan);
3009
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003010 l2cap_chan_lock(chan);
3011
Mat Martineau03625202012-05-17 20:53:51 -07003012 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3013 chan->last_acked_seq);
3014
3015 if (frames_to_ack)
3016 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003017
3018 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003019 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003020}
3021
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003022int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003023{
Mat Martineau3c588192012-04-11 10:48:42 -07003024 int err;
3025
Mat Martineau105bdf92012-04-27 16:50:48 -07003026 chan->next_tx_seq = 0;
3027 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003028 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003029 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003030 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003031 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003032 chan->last_acked_seq = 0;
3033 chan->sdu = NULL;
3034 chan->sdu_last_frag = NULL;
3035 chan->sdu_len = 0;
3036
Mat Martineaud34c34f2012-05-14 14:49:27 -07003037 skb_queue_head_init(&chan->tx_q);
3038
Mat Martineau08333282012-10-23 15:24:06 -07003039 chan->local_amp_id = 0;
3040 chan->move_id = 0;
3041 chan->move_state = L2CAP_MOVE_STABLE;
3042 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3043
Mat Martineau105bdf92012-04-27 16:50:48 -07003044 if (chan->mode != L2CAP_MODE_ERTM)
3045 return 0;
3046
3047 chan->rx_state = L2CAP_RX_STATE_RECV;
3048 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003049
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003050 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3051 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3052 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003053
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003054 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003055
Mat Martineau3c588192012-04-11 10:48:42 -07003056 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3057 if (err < 0)
3058 return err;
3059
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003060 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3061 if (err < 0)
3062 l2cap_seq_list_free(&chan->srej_list);
3063
3064 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003065}
3066
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003067static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3068{
3069 switch (mode) {
3070 case L2CAP_MODE_STREAMING:
3071 case L2CAP_MODE_ERTM:
3072 if (l2cap_mode_supported(mode, remote_feat_mask))
3073 return mode;
3074 /* fall through */
3075 default:
3076 return L2CAP_MODE_BASIC;
3077 }
3078}
3079
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003080static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
3081{
3082 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
3083}
3084
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003085static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
3086{
3087 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
3088}
3089
Mat Martineau36c86c82012-10-23 15:24:20 -07003090static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3091 struct l2cap_conf_rfc *rfc)
3092{
3093 if (chan->local_amp_id && chan->hs_hcon) {
3094 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3095
3096 /* Class 1 devices have must have ERTM timeouts
3097 * exceeding the Link Supervision Timeout. The
3098 * default Link Supervision Timeout for AMP
3099 * controllers is 10 seconds.
3100 *
3101 * Class 1 devices use 0xffffffff for their
3102 * best-effort flush timeout, so the clamping logic
3103 * will result in a timeout that meets the above
3104 * requirement. ERTM timeouts are 16-bit values, so
3105 * the maximum timeout is 65.535 seconds.
3106 */
3107
3108 /* Convert timeout to milliseconds and round */
3109 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3110
3111 /* This is the recommended formula for class 2 devices
3112 * that start ERTM timers when packets are sent to the
3113 * controller.
3114 */
3115 ertm_to = 3 * ertm_to + 500;
3116
3117 if (ertm_to > 0xffff)
3118 ertm_to = 0xffff;
3119
3120 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3121 rfc->monitor_timeout = rfc->retrans_timeout;
3122 } else {
3123 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3124 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3125 }
3126}
3127
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003128static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3129{
3130 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003131 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003132 /* use extended control field */
3133 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003134 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3135 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003136 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003137 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003138 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3139 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003140 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003141}
3142
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003143static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003144{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003145 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003146 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003147 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003148 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003149
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003150 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003151
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003152 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003153 goto done;
3154
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003155 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003156 case L2CAP_MODE_STREAMING:
3157 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003158 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003159 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003160
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003161 if (__l2cap_efs_supported(chan))
3162 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3163
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003164 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003165 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003166 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003167 break;
3168 }
3169
3170done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003171 if (chan->imtu != L2CAP_DEFAULT_MTU)
3172 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003173
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003174 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003175 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003176 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003177 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003178 break;
3179
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003180 rfc.mode = L2CAP_MODE_BASIC;
3181 rfc.txwin_size = 0;
3182 rfc.max_transmit = 0;
3183 rfc.retrans_timeout = 0;
3184 rfc.monitor_timeout = 0;
3185 rfc.max_pdu_size = 0;
3186
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003187 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003188 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003189 break;
3190
3191 case L2CAP_MODE_ERTM:
3192 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003193 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003194
3195 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003196
3197 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003198 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3199 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003200 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003201
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003202 l2cap_txwin_setup(chan);
3203
3204 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003205 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003206
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003207 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003208 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003209
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003210 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3211 l2cap_add_opt_efs(&ptr, chan);
3212
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003213 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3214 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003215 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003216
3217 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3218 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003219 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003220 chan->fcs = L2CAP_FCS_NONE;
3221 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3222 chan->fcs);
3223 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003224 break;
3225
3226 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003227 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003228 rfc.mode = L2CAP_MODE_STREAMING;
3229 rfc.txwin_size = 0;
3230 rfc.max_transmit = 0;
3231 rfc.retrans_timeout = 0;
3232 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003233
3234 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003235 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3236 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003237 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003238
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003239 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003240 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003241
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003242 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3243 l2cap_add_opt_efs(&ptr, chan);
3244
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003245 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3246 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003247 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003248 chan->fcs = L2CAP_FCS_NONE;
3249 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3250 chan->fcs);
3251 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003252 break;
3253 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003254
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003255 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003256 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003257
3258 return ptr - data;
3259}
3260
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003261static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003262{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003263 struct l2cap_conf_rsp *rsp = data;
3264 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003265 void *req = chan->conf_req;
3266 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003267 int type, hint, olen;
3268 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003269 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003270 struct l2cap_conf_efs efs;
3271 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003272 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003273 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003274 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003275
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003276 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003277
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003278 while (len >= L2CAP_CONF_OPT_SIZE) {
3279 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003280
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003281 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003282 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003283
3284 switch (type) {
3285 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003286 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003287 break;
3288
3289 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003290 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003291 break;
3292
3293 case L2CAP_CONF_QOS:
3294 break;
3295
Marcel Holtmann6464f352007-10-20 13:39:51 +02003296 case L2CAP_CONF_RFC:
3297 if (olen == sizeof(rfc))
3298 memcpy(&rfc, (void *) val, olen);
3299 break;
3300
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003301 case L2CAP_CONF_FCS:
3302 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003303 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003304 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003305
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003306 case L2CAP_CONF_EFS:
3307 remote_efs = 1;
3308 if (olen == sizeof(efs))
3309 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003310 break;
3311
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003312 case L2CAP_CONF_EWS:
3313 if (!enable_hs)
3314 return -ECONNREFUSED;
3315
3316 set_bit(FLAG_EXT_CTRL, &chan->flags);
3317 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003318 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003319 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003320 break;
3321
3322 default:
3323 if (hint)
3324 break;
3325
3326 result = L2CAP_CONF_UNKNOWN;
3327 *((u8 *) ptr++) = type;
3328 break;
3329 }
3330 }
3331
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003332 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003333 goto done;
3334
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003335 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003336 case L2CAP_MODE_STREAMING:
3337 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003338 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003339 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003340 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003341 break;
3342 }
3343
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003344 if (remote_efs) {
3345 if (__l2cap_efs_supported(chan))
3346 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3347 else
3348 return -ECONNREFUSED;
3349 }
3350
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003351 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003352 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003353
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003354 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003355 }
3356
3357done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003358 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003359 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003360 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003361
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003362 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003363 return -ECONNREFUSED;
3364
Gustavo Padovan2d792812012-10-06 10:07:01 +01003365 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3366 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003367 }
3368
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003369 if (result == L2CAP_CONF_SUCCESS) {
3370 /* Configure output options and let the other side know
3371 * which ones we don't like. */
3372
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003373 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3374 result = L2CAP_CONF_UNACCEPT;
3375 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003376 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003377 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003378 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003379 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003380
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003381 if (remote_efs) {
3382 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003383 efs.stype != L2CAP_SERV_NOTRAFIC &&
3384 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003385
3386 result = L2CAP_CONF_UNACCEPT;
3387
3388 if (chan->num_conf_req >= 1)
3389 return -ECONNREFUSED;
3390
3391 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003392 sizeof(efs),
3393 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003394 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003395 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003396 result = L2CAP_CONF_PENDING;
3397 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003398 }
3399 }
3400
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003401 switch (rfc.mode) {
3402 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003403 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003404 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003405 break;
3406
3407 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003408 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3409 chan->remote_tx_win = rfc.txwin_size;
3410 else
3411 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3412
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003413 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003414
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003415 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003416 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3417 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003418 rfc.max_pdu_size = cpu_to_le16(size);
3419 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003420
Mat Martineau36c86c82012-10-23 15:24:20 -07003421 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003422
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003423 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003424
3425 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003426 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003427
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003428 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3429 chan->remote_id = efs.id;
3430 chan->remote_stype = efs.stype;
3431 chan->remote_msdu = le16_to_cpu(efs.msdu);
3432 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003433 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003434 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003435 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003436 chan->remote_sdu_itime =
3437 le32_to_cpu(efs.sdu_itime);
3438 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003439 sizeof(efs),
3440 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003441 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003442 break;
3443
3444 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003445 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003446 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3447 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003448 rfc.max_pdu_size = cpu_to_le16(size);
3449 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003450
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003451 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003452
Gustavo Padovan2d792812012-10-06 10:07:01 +01003453 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3454 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003455
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003456 break;
3457
3458 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003459 result = L2CAP_CONF_UNACCEPT;
3460
3461 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003462 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003463 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003464
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003465 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003466 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003467 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003468 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003469 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003470 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003471
3472 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003473}
3474
Gustavo Padovan2d792812012-10-06 10:07:01 +01003475static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3476 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003477{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003478 struct l2cap_conf_req *req = data;
3479 void *ptr = req->data;
3480 int type, olen;
3481 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003482 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003483 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003484
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003485 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003486
3487 while (len >= L2CAP_CONF_OPT_SIZE) {
3488 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3489
3490 switch (type) {
3491 case L2CAP_CONF_MTU:
3492 if (val < L2CAP_DEFAULT_MIN_MTU) {
3493 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003494 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003495 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003496 chan->imtu = val;
3497 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003498 break;
3499
3500 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003501 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003502 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003503 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003504 break;
3505
3506 case L2CAP_CONF_RFC:
3507 if (olen == sizeof(rfc))
3508 memcpy(&rfc, (void *)val, olen);
3509
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003510 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003511 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003512 return -ECONNREFUSED;
3513
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003514 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003515
3516 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003517 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003518 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003519
3520 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003521 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003522 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003523 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003524 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003525
3526 case L2CAP_CONF_EFS:
3527 if (olen == sizeof(efs))
3528 memcpy(&efs, (void *)val, olen);
3529
3530 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003531 efs.stype != L2CAP_SERV_NOTRAFIC &&
3532 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003533 return -ECONNREFUSED;
3534
Gustavo Padovan2d792812012-10-06 10:07:01 +01003535 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3536 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003537 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003538
3539 case L2CAP_CONF_FCS:
3540 if (*result == L2CAP_CONF_PENDING)
3541 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003542 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003543 &chan->conf_state);
3544 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003545 }
3546 }
3547
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003548 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003549 return -ECONNREFUSED;
3550
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003551 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003552
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003553 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003554 switch (rfc.mode) {
3555 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003556 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3557 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3558 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003559 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3560 chan->ack_win = min_t(u16, chan->ack_win,
3561 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003562
3563 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3564 chan->local_msdu = le16_to_cpu(efs.msdu);
3565 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003566 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003567 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3568 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003569 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003570 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003571 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003572
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003573 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003574 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003575 }
3576 }
3577
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003578 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003579 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003580
3581 return ptr - data;
3582}
3583
Gustavo Padovan2d792812012-10-06 10:07:01 +01003584static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3585 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003586{
3587 struct l2cap_conf_rsp *rsp = data;
3588 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003589
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003590 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003591
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003592 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003593 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003594 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003595
3596 return ptr - data;
3597}
3598
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003599void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003600{
3601 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003602 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003603 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003604 u8 rsp_code;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003605
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003606 rsp.scid = cpu_to_le16(chan->dcid);
3607 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003608 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3609 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003610
3611 if (chan->hs_hcon)
3612 rsp_code = L2CAP_CREATE_CHAN_RSP;
3613 else
3614 rsp_code = L2CAP_CONN_RSP;
3615
3616 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3617
3618 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003619
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003620 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003621 return;
3622
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003623 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003624 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003625 chan->num_conf_req++;
3626}
3627
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003628static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003629{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003630 int type, olen;
3631 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003632 /* Use sane default values in case a misbehaving remote device
3633 * did not send an RFC or extended window size option.
3634 */
3635 u16 txwin_ext = chan->ack_win;
3636 struct l2cap_conf_rfc rfc = {
3637 .mode = chan->mode,
3638 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3639 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3640 .max_pdu_size = cpu_to_le16(chan->imtu),
3641 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3642 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003643
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003644 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003645
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003646 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003647 return;
3648
3649 while (len >= L2CAP_CONF_OPT_SIZE) {
3650 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3651
Mat Martineauc20f8e32012-07-10 05:47:07 -07003652 switch (type) {
3653 case L2CAP_CONF_RFC:
3654 if (olen == sizeof(rfc))
3655 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003656 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003657 case L2CAP_CONF_EWS:
3658 txwin_ext = val;
3659 break;
3660 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003661 }
3662
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003663 switch (rfc.mode) {
3664 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003665 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3666 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003667 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3668 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3669 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3670 else
3671 chan->ack_win = min_t(u16, chan->ack_win,
3672 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003673 break;
3674 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003675 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003676 }
3677}
3678
Gustavo Padovan2d792812012-10-06 10:07:01 +01003679static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003680 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3681 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003682{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003683 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003684
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003685 if (cmd_len < sizeof(*rej))
3686 return -EPROTO;
3687
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003688 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003689 return 0;
3690
3691 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003692 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003693 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003694
3695 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003696 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003697
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003698 l2cap_conn_start(conn);
3699 }
3700
3701 return 0;
3702}
3703
Mat Martineau17009152012-10-23 15:24:07 -07003704static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3705 struct l2cap_cmd_hdr *cmd,
3706 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003707{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003708 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3709 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003710 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003711 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003712 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003713
3714 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003715 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003716
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003717 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003718
3719 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003720 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003721 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003722 result = L2CAP_CR_BAD_PSM;
3723 goto sendresp;
3724 }
3725
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003726 parent = pchan->sk;
3727
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003728 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003729 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003730
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003731 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003732 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003733 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003734 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003735 result = L2CAP_CR_SEC_BLOCK;
3736 goto response;
3737 }
3738
Linus Torvalds1da177e2005-04-16 15:20:36 -07003739 result = L2CAP_CR_NO_MEM;
3740
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003741 /* Check if we already have channel with that dcid */
3742 if (__l2cap_get_chan_by_dcid(conn, scid))
3743 goto response;
3744
Gustavo Padovan80b98022012-05-27 22:27:51 -03003745 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003746 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003747 goto response;
3748
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003749 sk = chan->sk;
3750
Linus Torvalds1da177e2005-04-16 15:20:36 -07003751 hci_conn_hold(conn->hcon);
3752
Linus Torvalds1da177e2005-04-16 15:20:36 -07003753 bacpy(&bt_sk(sk)->src, conn->src);
3754 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003755 chan->psm = psm;
3756 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003757 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003758
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003759 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003760
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003761 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003762
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003763 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003764
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003765 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003766
Marcel Holtmann984947d2009-02-06 23:35:19 +01003767 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003768 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003769 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003770 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003771 result = L2CAP_CR_PEND;
3772 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003773 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003774 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003775 /* Force pending result for AMP controllers.
3776 * The connection will succeed after the
3777 * physical link is up.
3778 */
3779 if (amp_id) {
3780 __l2cap_state_change(chan, BT_CONNECT2);
3781 result = L2CAP_CR_PEND;
3782 } else {
3783 __l2cap_state_change(chan, BT_CONFIG);
3784 result = L2CAP_CR_SUCCESS;
3785 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003786 status = L2CAP_CS_NO_INFO;
3787 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003788 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003789 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003790 result = L2CAP_CR_PEND;
3791 status = L2CAP_CS_AUTHEN_PEND;
3792 }
3793 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003794 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003795 result = L2CAP_CR_PEND;
3796 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003797 }
3798
Linus Torvalds1da177e2005-04-16 15:20:36 -07003799response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003800 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003801 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003802
3803sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003804 rsp.scid = cpu_to_le16(scid);
3805 rsp.dcid = cpu_to_le16(dcid);
3806 rsp.result = cpu_to_le16(result);
3807 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003808 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003809
3810 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3811 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003812 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003813
3814 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3815 conn->info_ident = l2cap_get_ident(conn);
3816
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003817 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003818
Gustavo Padovan2d792812012-10-06 10:07:01 +01003819 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3820 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003821 }
3822
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003823 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003824 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003825 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003826 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003827 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003828 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003829 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003830 }
Mat Martineau17009152012-10-23 15:24:07 -07003831
3832 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003833}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003834
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003835static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003836 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003837{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303838 struct hci_dev *hdev = conn->hcon->hdev;
3839 struct hci_conn *hcon = conn->hcon;
3840
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003841 if (cmd_len < sizeof(struct l2cap_conn_req))
3842 return -EPROTO;
3843
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303844 hci_dev_lock(hdev);
3845 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3846 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3847 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3848 hcon->dst_type, 0, NULL, 0,
3849 hcon->dev_class);
3850 hci_dev_unlock(hdev);
3851
Gustavo Padovan300229f2012-10-12 19:40:40 +08003852 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003853 return 0;
3854}
3855
Mat Martineau5909cf32012-10-23 15:24:08 -07003856static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003857 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3858 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003859{
3860 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3861 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003862 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003863 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003864 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003865
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003866 if (cmd_len < sizeof(*rsp))
3867 return -EPROTO;
3868
Linus Torvalds1da177e2005-04-16 15:20:36 -07003869 scid = __le16_to_cpu(rsp->scid);
3870 dcid = __le16_to_cpu(rsp->dcid);
3871 result = __le16_to_cpu(rsp->result);
3872 status = __le16_to_cpu(rsp->status);
3873
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003874 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 +01003875 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003876
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003877 mutex_lock(&conn->chan_lock);
3878
Linus Torvalds1da177e2005-04-16 15:20:36 -07003879 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003880 chan = __l2cap_get_chan_by_scid(conn, scid);
3881 if (!chan) {
3882 err = -EFAULT;
3883 goto unlock;
3884 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003885 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003886 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3887 if (!chan) {
3888 err = -EFAULT;
3889 goto unlock;
3890 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003891 }
3892
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003893 err = 0;
3894
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003895 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003896
Linus Torvalds1da177e2005-04-16 15:20:36 -07003897 switch (result) {
3898 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003899 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003900 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003901 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003902 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003903
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003904 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003905 break;
3906
Linus Torvalds1da177e2005-04-16 15:20:36 -07003907 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003908 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003909 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003910 break;
3911
3912 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003913 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003914 break;
3915
3916 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003917 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003918 break;
3919 }
3920
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003921 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003922
3923unlock:
3924 mutex_unlock(&conn->chan_lock);
3925
3926 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003927}
3928
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003929static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003930{
3931 /* FCS is enabled only in ERTM or streaming mode, if one or both
3932 * sides request it.
3933 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003934 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003935 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003936 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003937 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003938}
3939
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003940static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3941 u8 ident, u16 flags)
3942{
3943 struct l2cap_conn *conn = chan->conn;
3944
3945 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3946 flags);
3947
3948 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3949 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3950
3951 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
3952 l2cap_build_conf_rsp(chan, data,
3953 L2CAP_CONF_SUCCESS, flags), data);
3954}
3955
Gustavo Padovan2d792812012-10-06 10:07:01 +01003956static inline int l2cap_config_req(struct l2cap_conn *conn,
3957 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3958 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003959{
3960 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3961 u16 dcid, flags;
3962 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003963 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003964 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003965
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003966 if (cmd_len < sizeof(*req))
3967 return -EPROTO;
3968
Linus Torvalds1da177e2005-04-16 15:20:36 -07003969 dcid = __le16_to_cpu(req->dcid);
3970 flags = __le16_to_cpu(req->flags);
3971
3972 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3973
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003974 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003975 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003976 return -ENOENT;
3977
David S. Miller033b1142011-07-21 13:38:42 -07003978 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003979 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003980
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003981 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003982 rej.scid = cpu_to_le16(chan->scid);
3983 rej.dcid = cpu_to_le16(chan->dcid);
3984
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003985 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003986 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003987 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003988 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003989
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003990 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003991 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003992 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003993 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003994 l2cap_build_conf_rsp(chan, rsp,
3995 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003996 goto unlock;
3997 }
3998
3999 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004000 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4001 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004002
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004003 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004004 /* Incomplete config. Send empty response. */
4005 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004006 l2cap_build_conf_rsp(chan, rsp,
4007 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004008 goto unlock;
4009 }
4010
4011 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004012 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004013 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004014 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004015 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004016 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004017
Mat Martineau1500109b2012-10-23 15:24:15 -07004018 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004019 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004020 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004021
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004022 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004023 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004024
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004025 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004026 goto unlock;
4027
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004028 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004029 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004030
Mat Martineau105bdf92012-04-27 16:50:48 -07004031 if (chan->mode == L2CAP_MODE_ERTM ||
4032 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004033 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004034
Mat Martineau3c588192012-04-11 10:48:42 -07004035 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004036 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004037 else
4038 l2cap_chan_ready(chan);
4039
Marcel Holtmann876d9482007-10-20 13:35:42 +02004040 goto unlock;
4041 }
4042
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004043 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004044 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004045 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004046 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004047 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004048 }
4049
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004050 /* Got Conf Rsp PENDING from remote side and asume we sent
4051 Conf Rsp PENDING in the code above */
4052 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004053 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004054
4055 /* check compatibility */
4056
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004057 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004058 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004059 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4060 else
4061 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004062 }
4063
Linus Torvalds1da177e2005-04-16 15:20:36 -07004064unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004065 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004066 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004067}
4068
Gustavo Padovan2d792812012-10-06 10:07:01 +01004069static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004070 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4071 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004072{
4073 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4074 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004075 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004076 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004077 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004078
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004079 if (cmd_len < sizeof(*rsp))
4080 return -EPROTO;
4081
Linus Torvalds1da177e2005-04-16 15:20:36 -07004082 scid = __le16_to_cpu(rsp->scid);
4083 flags = __le16_to_cpu(rsp->flags);
4084 result = __le16_to_cpu(rsp->result);
4085
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004086 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4087 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004088
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004089 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004090 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004091 return 0;
4092
4093 switch (result) {
4094 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004095 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004096 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004097 break;
4098
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004099 case L2CAP_CONF_PENDING:
4100 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4101
4102 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4103 char buf[64];
4104
4105 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004106 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004107 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004108 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004109 goto done;
4110 }
4111
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004112 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004113 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4114 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004115 } else {
4116 if (l2cap_check_efs(chan)) {
4117 amp_create_logical_link(chan);
4118 chan->ident = cmd->ident;
4119 }
4120 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004121 }
4122 goto done;
4123
Linus Torvalds1da177e2005-04-16 15:20:36 -07004124 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004125 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004126 char req[64];
4127
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004128 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004129 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004130 goto done;
4131 }
4132
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004133 /* throw out any old stored conf requests */
4134 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004135 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004136 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004137 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004138 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004139 goto done;
4140 }
4141
4142 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004143 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004144 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004145 if (result != L2CAP_CONF_SUCCESS)
4146 goto done;
4147 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004148 }
4149
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004150 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004151 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004152
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004153 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004154 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004155 goto done;
4156 }
4157
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004158 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004159 goto done;
4160
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004161 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004162
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004163 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004164 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004165
Mat Martineau105bdf92012-04-27 16:50:48 -07004166 if (chan->mode == L2CAP_MODE_ERTM ||
4167 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004168 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004169
Mat Martineau3c588192012-04-11 10:48:42 -07004170 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004171 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004172 else
4173 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004174 }
4175
4176done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004177 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004178 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004179}
4180
Gustavo Padovan2d792812012-10-06 10:07:01 +01004181static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004182 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4183 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004184{
4185 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4186 struct l2cap_disconn_rsp rsp;
4187 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004188 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004189 struct sock *sk;
4190
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004191 if (cmd_len != sizeof(*req))
4192 return -EPROTO;
4193
Linus Torvalds1da177e2005-04-16 15:20:36 -07004194 scid = __le16_to_cpu(req->scid);
4195 dcid = __le16_to_cpu(req->dcid);
4196
4197 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4198
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004199 mutex_lock(&conn->chan_lock);
4200
4201 chan = __l2cap_get_chan_by_scid(conn, dcid);
4202 if (!chan) {
4203 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004204 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004205 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004206
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004207 l2cap_chan_lock(chan);
4208
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004209 sk = chan->sk;
4210
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004211 rsp.dcid = cpu_to_le16(chan->scid);
4212 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004213 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4214
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004215 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004216 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004217 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004218
Mat Martineau61d6ef32012-04-27 16:50:50 -07004219 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004220 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004221
4222 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004223
Gustavo Padovan80b98022012-05-27 22:27:51 -03004224 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004225 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004226
4227 mutex_unlock(&conn->chan_lock);
4228
Linus Torvalds1da177e2005-04-16 15:20:36 -07004229 return 0;
4230}
4231
Gustavo Padovan2d792812012-10-06 10:07:01 +01004232static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004233 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4234 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004235{
4236 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4237 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004238 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004239
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004240 if (cmd_len != sizeof(*rsp))
4241 return -EPROTO;
4242
Linus Torvalds1da177e2005-04-16 15:20:36 -07004243 scid = __le16_to_cpu(rsp->scid);
4244 dcid = __le16_to_cpu(rsp->dcid);
4245
4246 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4247
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004248 mutex_lock(&conn->chan_lock);
4249
4250 chan = __l2cap_get_chan_by_scid(conn, scid);
4251 if (!chan) {
4252 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004253 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004254 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004255
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004256 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004257
Mat Martineau61d6ef32012-04-27 16:50:50 -07004258 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004259 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004260
4261 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004262
Gustavo Padovan80b98022012-05-27 22:27:51 -03004263 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004264 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004265
4266 mutex_unlock(&conn->chan_lock);
4267
Linus Torvalds1da177e2005-04-16 15:20:36 -07004268 return 0;
4269}
4270
Gustavo Padovan2d792812012-10-06 10:07:01 +01004271static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004272 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4273 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004274{
4275 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004276 u16 type;
4277
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004278 if (cmd_len != sizeof(*req))
4279 return -EPROTO;
4280
Linus Torvalds1da177e2005-04-16 15:20:36 -07004281 type = __le16_to_cpu(req->type);
4282
4283 BT_DBG("type 0x%4.4x", type);
4284
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004285 if (type == L2CAP_IT_FEAT_MASK) {
4286 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004287 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004288 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004289 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4290 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004291 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004292 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004293 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004294 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004295 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004296 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004297
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004298 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004299 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4300 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004301 } else if (type == L2CAP_IT_FIXED_CHAN) {
4302 u8 buf[12];
4303 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004304
4305 if (enable_hs)
4306 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4307 else
4308 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4309
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004310 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4311 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004312 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004313 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4314 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004315 } else {
4316 struct l2cap_info_rsp rsp;
4317 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004318 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004319 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4320 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004321 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004322
4323 return 0;
4324}
4325
Gustavo Padovan2d792812012-10-06 10:07:01 +01004326static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004327 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4328 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004329{
4330 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4331 u16 type, result;
4332
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004333 if (cmd_len != sizeof(*rsp))
4334 return -EPROTO;
4335
Linus Torvalds1da177e2005-04-16 15:20:36 -07004336 type = __le16_to_cpu(rsp->type);
4337 result = __le16_to_cpu(rsp->result);
4338
4339 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4340
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004341 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4342 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004343 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004344 return 0;
4345
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004346 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004347
Ville Tervoadb08ed2010-08-04 09:43:33 +03004348 if (result != L2CAP_IR_SUCCESS) {
4349 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4350 conn->info_ident = 0;
4351
4352 l2cap_conn_start(conn);
4353
4354 return 0;
4355 }
4356
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004357 switch (type) {
4358 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004359 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004360
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004361 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004362 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004363 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004364
4365 conn->info_ident = l2cap_get_ident(conn);
4366
4367 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004368 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004369 } else {
4370 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4371 conn->info_ident = 0;
4372
4373 l2cap_conn_start(conn);
4374 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004375 break;
4376
4377 case L2CAP_IT_FIXED_CHAN:
4378 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004379 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004380 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004381
4382 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004383 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004384 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004385
Linus Torvalds1da177e2005-04-16 15:20:36 -07004386 return 0;
4387}
4388
Mat Martineau17009152012-10-23 15:24:07 -07004389static int l2cap_create_channel_req(struct l2cap_conn *conn,
4390 struct l2cap_cmd_hdr *cmd,
4391 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004392{
4393 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004394 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004395 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004396 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004397 u16 psm, scid;
4398
4399 if (cmd_len != sizeof(*req))
4400 return -EPROTO;
4401
4402 if (!enable_hs)
4403 return -EINVAL;
4404
4405 psm = le16_to_cpu(req->psm);
4406 scid = le16_to_cpu(req->scid);
4407
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004408 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 -07004409
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004410 /* For controller id 0 make BR/EDR connection */
4411 if (req->amp_id == HCI_BREDR_ID) {
4412 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4413 req->amp_id);
4414 return 0;
4415 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004416
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004417 /* Validate AMP controller id */
4418 hdev = hci_dev_get(req->amp_id);
4419 if (!hdev)
4420 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004421
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004422 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004423 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004424 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004425 }
4426
4427 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4428 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004429 if (chan) {
4430 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4431 struct hci_conn *hs_hcon;
4432
4433 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, conn->dst);
4434 if (!hs_hcon) {
4435 hci_dev_put(hdev);
4436 return -EFAULT;
4437 }
4438
4439 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4440
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004441 mgr->bredr_chan = chan;
4442 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004443 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004444 conn->mtu = hdev->block_mtu;
4445 }
4446
4447 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004448
4449 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004450
4451error:
4452 rsp.dcid = 0;
4453 rsp.scid = cpu_to_le16(scid);
4454 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4455 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4456
4457 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4458 sizeof(rsp), &rsp);
4459
4460 return -EFAULT;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004461}
4462
Mat Martineau8eb200b2012-10-23 15:24:17 -07004463static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4464{
4465 struct l2cap_move_chan_req req;
4466 u8 ident;
4467
4468 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4469
4470 ident = l2cap_get_ident(chan->conn);
4471 chan->ident = ident;
4472
4473 req.icid = cpu_to_le16(chan->scid);
4474 req.dest_amp_id = dest_amp_id;
4475
4476 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4477 &req);
4478
4479 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4480}
4481
Mat Martineau1500109b2012-10-23 15:24:15 -07004482static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004483{
4484 struct l2cap_move_chan_rsp rsp;
4485
Mat Martineau1500109b2012-10-23 15:24:15 -07004486 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004487
Mat Martineau1500109b2012-10-23 15:24:15 -07004488 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004489 rsp.result = cpu_to_le16(result);
4490
Mat Martineau1500109b2012-10-23 15:24:15 -07004491 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4492 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004493}
4494
Mat Martineau5b155ef2012-10-23 15:24:14 -07004495static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004496{
4497 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004498
Mat Martineau5b155ef2012-10-23 15:24:14 -07004499 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004500
Mat Martineau5b155ef2012-10-23 15:24:14 -07004501 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004502
Mat Martineau5b155ef2012-10-23 15:24:14 -07004503 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004504 cfm.result = cpu_to_le16(result);
4505
Mat Martineau5b155ef2012-10-23 15:24:14 -07004506 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4507 sizeof(cfm), &cfm);
4508
4509 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4510}
4511
4512static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4513{
4514 struct l2cap_move_chan_cfm cfm;
4515
4516 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4517
4518 cfm.icid = cpu_to_le16(icid);
4519 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4520
4521 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4522 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004523}
4524
4525static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004526 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004527{
4528 struct l2cap_move_chan_cfm_rsp rsp;
4529
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004530 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004531
4532 rsp.icid = cpu_to_le16(icid);
4533 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4534}
4535
Mat Martineau5f3847a2012-10-23 15:24:12 -07004536static void __release_logical_link(struct l2cap_chan *chan)
4537{
4538 chan->hs_hchan = NULL;
4539 chan->hs_hcon = NULL;
4540
4541 /* Placeholder - release the logical link */
4542}
4543
Mat Martineau1500109b2012-10-23 15:24:15 -07004544static void l2cap_logical_fail(struct l2cap_chan *chan)
4545{
4546 /* Logical link setup failed */
4547 if (chan->state != BT_CONNECTED) {
4548 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004549 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004550 return;
4551 }
4552
4553 switch (chan->move_role) {
4554 case L2CAP_MOVE_ROLE_RESPONDER:
4555 l2cap_move_done(chan);
4556 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4557 break;
4558 case L2CAP_MOVE_ROLE_INITIATOR:
4559 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4560 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4561 /* Remote has only sent pending or
4562 * success responses, clean up
4563 */
4564 l2cap_move_done(chan);
4565 }
4566
4567 /* Other amp move states imply that the move
4568 * has already aborted
4569 */
4570 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4571 break;
4572 }
4573}
4574
4575static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4576 struct hci_chan *hchan)
4577{
4578 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004579
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004580 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004581 chan->hs_hcon->l2cap_data = chan->conn;
4582
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004583 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004584
4585 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004586 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004587
4588 set_default_fcs(chan);
4589
4590 err = l2cap_ertm_init(chan);
4591 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004592 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004593 else
4594 l2cap_chan_ready(chan);
4595 }
4596}
4597
4598static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4599 struct hci_chan *hchan)
4600{
4601 chan->hs_hcon = hchan->conn;
4602 chan->hs_hcon->l2cap_data = chan->conn;
4603
4604 BT_DBG("move_state %d", chan->move_state);
4605
4606 switch (chan->move_state) {
4607 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4608 /* Move confirm will be sent after a success
4609 * response is received
4610 */
4611 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4612 break;
4613 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4614 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4615 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4616 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4617 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4618 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4619 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4620 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4621 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4622 }
4623 break;
4624 default:
4625 /* Move was not in expected state, free the channel */
4626 __release_logical_link(chan);
4627
4628 chan->move_state = L2CAP_MOVE_STABLE;
4629 }
4630}
4631
4632/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004633void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4634 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004635{
Mat Martineau1500109b2012-10-23 15:24:15 -07004636 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4637
4638 if (status) {
4639 l2cap_logical_fail(chan);
4640 __release_logical_link(chan);
4641 return;
4642 }
4643
4644 if (chan->state != BT_CONNECTED) {
4645 /* Ignore logical link if channel is on BR/EDR */
4646 if (chan->local_amp_id)
4647 l2cap_logical_finish_create(chan, hchan);
4648 } else {
4649 l2cap_logical_finish_move(chan, hchan);
4650 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004651}
4652
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004653void l2cap_move_start(struct l2cap_chan *chan)
4654{
4655 BT_DBG("chan %p", chan);
4656
4657 if (chan->local_amp_id == HCI_BREDR_ID) {
4658 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4659 return;
4660 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4661 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4662 /* Placeholder - start physical link setup */
4663 } else {
4664 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4665 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4666 chan->move_id = 0;
4667 l2cap_move_setup(chan);
4668 l2cap_send_move_chan_req(chan, 0);
4669 }
4670}
4671
Mat Martineau8eb200b2012-10-23 15:24:17 -07004672static void l2cap_do_create(struct l2cap_chan *chan, int result,
4673 u8 local_amp_id, u8 remote_amp_id)
4674{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004675 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4676 local_amp_id, remote_amp_id);
4677
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004678 chan->fcs = L2CAP_FCS_NONE;
4679
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004680 /* Outgoing channel on AMP */
4681 if (chan->state == BT_CONNECT) {
4682 if (result == L2CAP_CR_SUCCESS) {
4683 chan->local_amp_id = local_amp_id;
4684 l2cap_send_create_chan_req(chan, remote_amp_id);
4685 } else {
4686 /* Revert to BR/EDR connect */
4687 l2cap_send_conn_req(chan);
4688 }
4689
4690 return;
4691 }
4692
4693 /* Incoming channel on AMP */
4694 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004695 struct l2cap_conn_rsp rsp;
4696 char buf[128];
4697 rsp.scid = cpu_to_le16(chan->dcid);
4698 rsp.dcid = cpu_to_le16(chan->scid);
4699
Mat Martineau8eb200b2012-10-23 15:24:17 -07004700 if (result == L2CAP_CR_SUCCESS) {
4701 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004702 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4703 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004704 } else {
4705 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004706 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4707 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004708 }
4709
4710 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4711 sizeof(rsp), &rsp);
4712
4713 if (result == L2CAP_CR_SUCCESS) {
4714 __l2cap_state_change(chan, BT_CONFIG);
4715 set_bit(CONF_REQ_SENT, &chan->conf_state);
4716 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4717 L2CAP_CONF_REQ,
4718 l2cap_build_conf_req(chan, buf), buf);
4719 chan->num_conf_req++;
4720 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004721 }
4722}
4723
4724static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4725 u8 remote_amp_id)
4726{
4727 l2cap_move_setup(chan);
4728 chan->move_id = local_amp_id;
4729 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4730
4731 l2cap_send_move_chan_req(chan, remote_amp_id);
4732}
4733
4734static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4735{
4736 struct hci_chan *hchan = NULL;
4737
4738 /* Placeholder - get hci_chan for logical link */
4739
4740 if (hchan) {
4741 if (hchan->state == BT_CONNECTED) {
4742 /* Logical link is ready to go */
4743 chan->hs_hcon = hchan->conn;
4744 chan->hs_hcon->l2cap_data = chan->conn;
4745 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4746 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4747
4748 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4749 } else {
4750 /* Wait for logical link to be ready */
4751 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4752 }
4753 } else {
4754 /* Logical link not available */
4755 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4756 }
4757}
4758
4759static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4760{
4761 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4762 u8 rsp_result;
4763 if (result == -EINVAL)
4764 rsp_result = L2CAP_MR_BAD_ID;
4765 else
4766 rsp_result = L2CAP_MR_NOT_ALLOWED;
4767
4768 l2cap_send_move_chan_rsp(chan, rsp_result);
4769 }
4770
4771 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4772 chan->move_state = L2CAP_MOVE_STABLE;
4773
4774 /* Restart data transmission */
4775 l2cap_ertm_send(chan);
4776}
4777
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004778/* Invoke with locked chan */
4779void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004780{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004781 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004782 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004783
Mat Martineau8eb200b2012-10-23 15:24:17 -07004784 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4785 chan, result, local_amp_id, remote_amp_id);
4786
Mat Martineau8eb200b2012-10-23 15:24:17 -07004787 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4788 l2cap_chan_unlock(chan);
4789 return;
4790 }
4791
4792 if (chan->state != BT_CONNECTED) {
4793 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4794 } else if (result != L2CAP_MR_SUCCESS) {
4795 l2cap_do_move_cancel(chan, result);
4796 } else {
4797 switch (chan->move_role) {
4798 case L2CAP_MOVE_ROLE_INITIATOR:
4799 l2cap_do_move_initiate(chan, local_amp_id,
4800 remote_amp_id);
4801 break;
4802 case L2CAP_MOVE_ROLE_RESPONDER:
4803 l2cap_do_move_respond(chan, result);
4804 break;
4805 default:
4806 l2cap_do_move_cancel(chan, result);
4807 break;
4808 }
4809 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004810}
4811
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004812static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004813 struct l2cap_cmd_hdr *cmd,
4814 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004815{
4816 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004817 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004818 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004819 u16 icid = 0;
4820 u16 result = L2CAP_MR_NOT_ALLOWED;
4821
4822 if (cmd_len != sizeof(*req))
4823 return -EPROTO;
4824
4825 icid = le16_to_cpu(req->icid);
4826
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004827 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004828
4829 if (!enable_hs)
4830 return -EINVAL;
4831
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004832 chan = l2cap_get_chan_by_dcid(conn, icid);
4833 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004834 rsp.icid = cpu_to_le16(icid);
4835 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4836 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4837 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004838 return 0;
4839 }
4840
Mat Martineau1500109b2012-10-23 15:24:15 -07004841 chan->ident = cmd->ident;
4842
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004843 if (chan->scid < L2CAP_CID_DYN_START ||
4844 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4845 (chan->mode != L2CAP_MODE_ERTM &&
4846 chan->mode != L2CAP_MODE_STREAMING)) {
4847 result = L2CAP_MR_NOT_ALLOWED;
4848 goto send_move_response;
4849 }
4850
4851 if (chan->local_amp_id == req->dest_amp_id) {
4852 result = L2CAP_MR_SAME_ID;
4853 goto send_move_response;
4854 }
4855
4856 if (req->dest_amp_id) {
4857 struct hci_dev *hdev;
4858 hdev = hci_dev_get(req->dest_amp_id);
4859 if (!hdev || hdev->dev_type != HCI_AMP ||
4860 !test_bit(HCI_UP, &hdev->flags)) {
4861 if (hdev)
4862 hci_dev_put(hdev);
4863
4864 result = L2CAP_MR_BAD_ID;
4865 goto send_move_response;
4866 }
4867 hci_dev_put(hdev);
4868 }
4869
4870 /* Detect a move collision. Only send a collision response
4871 * if this side has "lost", otherwise proceed with the move.
4872 * The winner has the larger bd_addr.
4873 */
4874 if ((__chan_is_moving(chan) ||
4875 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
4876 bacmp(conn->src, conn->dst) > 0) {
4877 result = L2CAP_MR_COLLISION;
4878 goto send_move_response;
4879 }
4880
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004881 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4882 l2cap_move_setup(chan);
4883 chan->move_id = req->dest_amp_id;
4884 icid = chan->dcid;
4885
4886 if (!req->dest_amp_id) {
4887 /* Moving to BR/EDR */
4888 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4889 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4890 result = L2CAP_MR_PEND;
4891 } else {
4892 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4893 result = L2CAP_MR_SUCCESS;
4894 }
4895 } else {
4896 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4897 /* Placeholder - uncomment when amp functions are available */
4898 /*amp_accept_physical(chan, req->dest_amp_id);*/
4899 result = L2CAP_MR_PEND;
4900 }
4901
4902send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004903 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004904
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004905 l2cap_chan_unlock(chan);
4906
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004907 return 0;
4908}
4909
Mat Martineau5b155ef2012-10-23 15:24:14 -07004910static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4911{
4912 struct l2cap_chan *chan;
4913 struct hci_chan *hchan = NULL;
4914
4915 chan = l2cap_get_chan_by_scid(conn, icid);
4916 if (!chan) {
4917 l2cap_send_move_chan_cfm_icid(conn, icid);
4918 return;
4919 }
4920
4921 __clear_chan_timer(chan);
4922 if (result == L2CAP_MR_PEND)
4923 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4924
4925 switch (chan->move_state) {
4926 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4927 /* Move confirm will be sent when logical link
4928 * is complete.
4929 */
4930 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4931 break;
4932 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4933 if (result == L2CAP_MR_PEND) {
4934 break;
4935 } else if (test_bit(CONN_LOCAL_BUSY,
4936 &chan->conn_state)) {
4937 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4938 } else {
4939 /* Logical link is up or moving to BR/EDR,
4940 * proceed with move
4941 */
4942 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4943 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4944 }
4945 break;
4946 case L2CAP_MOVE_WAIT_RSP:
4947 /* Moving to AMP */
4948 if (result == L2CAP_MR_SUCCESS) {
4949 /* Remote is ready, send confirm immediately
4950 * after logical link is ready
4951 */
4952 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4953 } else {
4954 /* Both logical link and move success
4955 * are required to confirm
4956 */
4957 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
4958 }
4959
4960 /* Placeholder - get hci_chan for logical link */
4961 if (!hchan) {
4962 /* Logical link not available */
4963 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4964 break;
4965 }
4966
4967 /* If the logical link is not yet connected, do not
4968 * send confirmation.
4969 */
4970 if (hchan->state != BT_CONNECTED)
4971 break;
4972
4973 /* Logical link is already ready to go */
4974
4975 chan->hs_hcon = hchan->conn;
4976 chan->hs_hcon->l2cap_data = chan->conn;
4977
4978 if (result == L2CAP_MR_SUCCESS) {
4979 /* Can confirm now */
4980 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4981 } else {
4982 /* Now only need move success
4983 * to confirm
4984 */
4985 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4986 }
4987
4988 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4989 break;
4990 default:
4991 /* Any other amp move state means the move failed. */
4992 chan->move_id = chan->local_amp_id;
4993 l2cap_move_done(chan);
4994 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4995 }
4996
4997 l2cap_chan_unlock(chan);
4998}
4999
5000static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5001 u16 result)
5002{
5003 struct l2cap_chan *chan;
5004
5005 chan = l2cap_get_chan_by_ident(conn, ident);
5006 if (!chan) {
5007 /* Could not locate channel, icid is best guess */
5008 l2cap_send_move_chan_cfm_icid(conn, icid);
5009 return;
5010 }
5011
5012 __clear_chan_timer(chan);
5013
5014 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5015 if (result == L2CAP_MR_COLLISION) {
5016 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5017 } else {
5018 /* Cleanup - cancel move */
5019 chan->move_id = chan->local_amp_id;
5020 l2cap_move_done(chan);
5021 }
5022 }
5023
5024 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5025
5026 l2cap_chan_unlock(chan);
5027}
5028
5029static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5030 struct l2cap_cmd_hdr *cmd,
5031 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005032{
5033 struct l2cap_move_chan_rsp *rsp = data;
5034 u16 icid, result;
5035
5036 if (cmd_len != sizeof(*rsp))
5037 return -EPROTO;
5038
5039 icid = le16_to_cpu(rsp->icid);
5040 result = le16_to_cpu(rsp->result);
5041
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005042 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005043
Mat Martineau5b155ef2012-10-23 15:24:14 -07005044 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5045 l2cap_move_continue(conn, icid, result);
5046 else
5047 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005048
5049 return 0;
5050}
5051
Mat Martineau5f3847a2012-10-23 15:24:12 -07005052static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5053 struct l2cap_cmd_hdr *cmd,
5054 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005055{
5056 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005057 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005058 u16 icid, result;
5059
5060 if (cmd_len != sizeof(*cfm))
5061 return -EPROTO;
5062
5063 icid = le16_to_cpu(cfm->icid);
5064 result = le16_to_cpu(cfm->result);
5065
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005066 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005067
Mat Martineau5f3847a2012-10-23 15:24:12 -07005068 chan = l2cap_get_chan_by_dcid(conn, icid);
5069 if (!chan) {
5070 /* Spec requires a response even if the icid was not found */
5071 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5072 return 0;
5073 }
5074
5075 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5076 if (result == L2CAP_MC_CONFIRMED) {
5077 chan->local_amp_id = chan->move_id;
5078 if (!chan->local_amp_id)
5079 __release_logical_link(chan);
5080 } else {
5081 chan->move_id = chan->local_amp_id;
5082 }
5083
5084 l2cap_move_done(chan);
5085 }
5086
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005087 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5088
Mat Martineau5f3847a2012-10-23 15:24:12 -07005089 l2cap_chan_unlock(chan);
5090
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005091 return 0;
5092}
5093
5094static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005095 struct l2cap_cmd_hdr *cmd,
5096 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005097{
5098 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005099 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005100 u16 icid;
5101
5102 if (cmd_len != sizeof(*rsp))
5103 return -EPROTO;
5104
5105 icid = le16_to_cpu(rsp->icid);
5106
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005107 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005108
Mat Martineau3fd71a02012-10-23 15:24:16 -07005109 chan = l2cap_get_chan_by_scid(conn, icid);
5110 if (!chan)
5111 return 0;
5112
5113 __clear_chan_timer(chan);
5114
5115 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5116 chan->local_amp_id = chan->move_id;
5117
5118 if (!chan->local_amp_id && chan->hs_hchan)
5119 __release_logical_link(chan);
5120
5121 l2cap_move_done(chan);
5122 }
5123
5124 l2cap_chan_unlock(chan);
5125
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005126 return 0;
5127}
5128
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005129static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005130 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005131{
5132 u16 max_latency;
5133
5134 if (min > max || min < 6 || max > 3200)
5135 return -EINVAL;
5136
5137 if (to_multiplier < 10 || to_multiplier > 3200)
5138 return -EINVAL;
5139
5140 if (max >= to_multiplier * 8)
5141 return -EINVAL;
5142
5143 max_latency = (to_multiplier * 8 / max) - 1;
5144 if (latency > 499 || latency > max_latency)
5145 return -EINVAL;
5146
5147 return 0;
5148}
5149
5150static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005151 struct l2cap_cmd_hdr *cmd,
5152 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005153{
5154 struct hci_conn *hcon = conn->hcon;
5155 struct l2cap_conn_param_update_req *req;
5156 struct l2cap_conn_param_update_rsp rsp;
5157 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005158 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005159
5160 if (!(hcon->link_mode & HCI_LM_MASTER))
5161 return -EINVAL;
5162
5163 cmd_len = __le16_to_cpu(cmd->len);
5164 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5165 return -EPROTO;
5166
5167 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005168 min = __le16_to_cpu(req->min);
5169 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005170 latency = __le16_to_cpu(req->latency);
5171 to_multiplier = __le16_to_cpu(req->to_multiplier);
5172
5173 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 +01005174 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005175
5176 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005177
5178 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5179 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005180 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005181 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005182 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005183
5184 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005185 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005186
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005187 if (!err)
5188 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5189
Claudio Takahaside731152011-02-11 19:28:55 -02005190 return 0;
5191}
5192
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005193static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005194 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5195 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005196{
5197 int err = 0;
5198
5199 switch (cmd->code) {
5200 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005201 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005202 break;
5203
5204 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005205 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005206 break;
5207
5208 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005209 case L2CAP_CREATE_CHAN_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005210 err = l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005211 break;
5212
5213 case L2CAP_CONF_REQ:
5214 err = l2cap_config_req(conn, cmd, cmd_len, data);
5215 break;
5216
5217 case L2CAP_CONF_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005218 err = l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005219 break;
5220
5221 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005222 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005223 break;
5224
5225 case L2CAP_DISCONN_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005226 err = l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005227 break;
5228
5229 case L2CAP_ECHO_REQ:
5230 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5231 break;
5232
5233 case L2CAP_ECHO_RSP:
5234 break;
5235
5236 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005237 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005238 break;
5239
5240 case L2CAP_INFO_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005241 err = l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005242 break;
5243
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005244 case L2CAP_CREATE_CHAN_REQ:
5245 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5246 break;
5247
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005248 case L2CAP_MOVE_CHAN_REQ:
5249 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5250 break;
5251
5252 case L2CAP_MOVE_CHAN_RSP:
5253 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
5254 break;
5255
5256 case L2CAP_MOVE_CHAN_CFM:
5257 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5258 break;
5259
5260 case L2CAP_MOVE_CHAN_CFM_RSP:
5261 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
5262 break;
5263
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005264 default:
5265 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5266 err = -EINVAL;
5267 break;
5268 }
5269
5270 return err;
5271}
5272
5273static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005274 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005275{
5276 switch (cmd->code) {
5277 case L2CAP_COMMAND_REJ:
5278 return 0;
5279
5280 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02005281 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005282
5283 case L2CAP_CONN_PARAM_UPDATE_RSP:
5284 return 0;
5285
5286 default:
5287 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5288 return -EINVAL;
5289 }
5290}
5291
Johan Hedbergc5623552013-04-29 19:35:33 +03005292static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5293 struct sk_buff *skb)
5294{
5295 u8 *data = skb->data;
5296 int len = skb->len;
5297 struct l2cap_cmd_hdr cmd;
5298 int err;
5299
5300 l2cap_raw_recv(conn, skb);
5301
5302 while (len >= L2CAP_CMD_HDR_SIZE) {
5303 u16 cmd_len;
5304 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5305 data += L2CAP_CMD_HDR_SIZE;
5306 len -= L2CAP_CMD_HDR_SIZE;
5307
5308 cmd_len = le16_to_cpu(cmd.len);
5309
5310 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5311 cmd.ident);
5312
5313 if (cmd_len > len || !cmd.ident) {
5314 BT_DBG("corrupted command");
5315 break;
5316 }
5317
5318 err = l2cap_le_sig_cmd(conn, &cmd, data);
5319 if (err) {
5320 struct l2cap_cmd_rej_unk rej;
5321
5322 BT_ERR("Wrong link type (%d)", err);
5323
5324 /* FIXME: Map err to a valid reason */
5325 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
5326 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5327 sizeof(rej), &rej);
5328 }
5329
5330 data += cmd_len;
5331 len -= cmd_len;
5332 }
5333
5334 kfree_skb(skb);
5335}
5336
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005337static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005338 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005339{
5340 u8 *data = skb->data;
5341 int len = skb->len;
5342 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005343 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005344
5345 l2cap_raw_recv(conn, skb);
5346
5347 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005348 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005349 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5350 data += L2CAP_CMD_HDR_SIZE;
5351 len -= L2CAP_CMD_HDR_SIZE;
5352
Al Viro88219a02007-07-29 00:17:25 -07005353 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005354
Gustavo Padovan2d792812012-10-06 10:07:01 +01005355 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5356 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005357
Al Viro88219a02007-07-29 00:17:25 -07005358 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005359 BT_DBG("corrupted command");
5360 break;
5361 }
5362
Johan Hedbergc5623552013-04-29 19:35:33 +03005363 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005364 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005365 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005366
5367 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005368
5369 /* FIXME: Map err to a valid reason */
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005370 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005371 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5372 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005373 }
5374
Al Viro88219a02007-07-29 00:17:25 -07005375 data += cmd_len;
5376 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005377 }
5378
5379 kfree_skb(skb);
5380}
5381
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005382static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005383{
5384 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005385 int hdr_size;
5386
5387 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5388 hdr_size = L2CAP_EXT_HDR_SIZE;
5389 else
5390 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005391
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005392 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005393 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005394 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5395 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5396
5397 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005398 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005399 }
5400 return 0;
5401}
5402
Mat Martineau6ea00482012-05-17 20:53:52 -07005403static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005404{
Mat Martineaue31f7632012-05-17 20:53:41 -07005405 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005406
Mat Martineaue31f7632012-05-17 20:53:41 -07005407 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005408
Mat Martineaue31f7632012-05-17 20:53:41 -07005409 memset(&control, 0, sizeof(control));
5410 control.sframe = 1;
5411 control.final = 1;
5412 control.reqseq = chan->buffer_seq;
5413 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005414
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005415 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005416 control.super = L2CAP_SUPER_RNR;
5417 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005418 }
5419
Mat Martineaue31f7632012-05-17 20:53:41 -07005420 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5421 chan->unacked_frames > 0)
5422 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005423
Mat Martineaue31f7632012-05-17 20:53:41 -07005424 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005425 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005426
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005427 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005428 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5429 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5430 * send it now.
5431 */
5432 control.super = L2CAP_SUPER_RR;
5433 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005434 }
5435}
5436
Gustavo Padovan2d792812012-10-06 10:07:01 +01005437static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5438 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005439{
Mat Martineau84084a32011-07-22 14:54:00 -07005440 /* skb->len reflects data in skb as well as all fragments
5441 * skb->data_len reflects only data in fragments
5442 */
5443 if (!skb_has_frag_list(skb))
5444 skb_shinfo(skb)->frag_list = new_frag;
5445
5446 new_frag->next = NULL;
5447
5448 (*last_frag)->next = new_frag;
5449 *last_frag = new_frag;
5450
5451 skb->len += new_frag->len;
5452 skb->data_len += new_frag->len;
5453 skb->truesize += new_frag->truesize;
5454}
5455
Mat Martineau4b51dae92012-05-17 20:53:37 -07005456static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5457 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005458{
5459 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005460
Mat Martineau4b51dae92012-05-17 20:53:37 -07005461 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005462 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005463 if (chan->sdu)
5464 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005465
Gustavo Padovan80b98022012-05-27 22:27:51 -03005466 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005467 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005468
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005469 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005470 if (chan->sdu)
5471 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005472
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005473 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005474 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005475
Mat Martineau84084a32011-07-22 14:54:00 -07005476 if (chan->sdu_len > chan->imtu) {
5477 err = -EMSGSIZE;
5478 break;
5479 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005480
Mat Martineau84084a32011-07-22 14:54:00 -07005481 if (skb->len >= chan->sdu_len)
5482 break;
5483
5484 chan->sdu = skb;
5485 chan->sdu_last_frag = skb;
5486
5487 skb = NULL;
5488 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005489 break;
5490
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005491 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005492 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005493 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005494
Mat Martineau84084a32011-07-22 14:54:00 -07005495 append_skb_frag(chan->sdu, skb,
5496 &chan->sdu_last_frag);
5497 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005498
Mat Martineau84084a32011-07-22 14:54:00 -07005499 if (chan->sdu->len >= chan->sdu_len)
5500 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005501
Mat Martineau84084a32011-07-22 14:54:00 -07005502 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005503 break;
5504
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005505 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005506 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005507 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005508
Mat Martineau84084a32011-07-22 14:54:00 -07005509 append_skb_frag(chan->sdu, skb,
5510 &chan->sdu_last_frag);
5511 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005512
Mat Martineau84084a32011-07-22 14:54:00 -07005513 if (chan->sdu->len != chan->sdu_len)
5514 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005515
Gustavo Padovan80b98022012-05-27 22:27:51 -03005516 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005517
Mat Martineau84084a32011-07-22 14:54:00 -07005518 if (!err) {
5519 /* Reassembly complete */
5520 chan->sdu = NULL;
5521 chan->sdu_last_frag = NULL;
5522 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005523 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005524 break;
5525 }
5526
Mat Martineau84084a32011-07-22 14:54:00 -07005527 if (err) {
5528 kfree_skb(skb);
5529 kfree_skb(chan->sdu);
5530 chan->sdu = NULL;
5531 chan->sdu_last_frag = NULL;
5532 chan->sdu_len = 0;
5533 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005534
Mat Martineau84084a32011-07-22 14:54:00 -07005535 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005536}
5537
Mat Martineau32b32732012-10-23 15:24:11 -07005538static int l2cap_resegment(struct l2cap_chan *chan)
5539{
5540 /* Placeholder */
5541 return 0;
5542}
5543
Mat Martineaue3281402011-07-07 09:39:02 -07005544void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03005545{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005546 u8 event;
5547
5548 if (chan->mode != L2CAP_MODE_ERTM)
5549 return;
5550
5551 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005552 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005553}
5554
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005555static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5556{
Mat Martineau63838722012-05-17 20:53:45 -07005557 int err = 0;
5558 /* Pass sequential frames to l2cap_reassemble_sdu()
5559 * until a gap is encountered.
5560 */
5561
5562 BT_DBG("chan %p", chan);
5563
5564 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5565 struct sk_buff *skb;
5566 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5567 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5568
5569 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5570
5571 if (!skb)
5572 break;
5573
5574 skb_unlink(skb, &chan->srej_q);
5575 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5576 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5577 if (err)
5578 break;
5579 }
5580
5581 if (skb_queue_empty(&chan->srej_q)) {
5582 chan->rx_state = L2CAP_RX_STATE_RECV;
5583 l2cap_send_ack(chan);
5584 }
5585
5586 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005587}
5588
5589static void l2cap_handle_srej(struct l2cap_chan *chan,
5590 struct l2cap_ctrl *control)
5591{
Mat Martineauf80842a2012-05-17 20:53:46 -07005592 struct sk_buff *skb;
5593
5594 BT_DBG("chan %p, control %p", chan, control);
5595
5596 if (control->reqseq == chan->next_tx_seq) {
5597 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005598 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005599 return;
5600 }
5601
5602 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5603
5604 if (skb == NULL) {
5605 BT_DBG("Seq %d not available for retransmission",
5606 control->reqseq);
5607 return;
5608 }
5609
5610 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5611 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005612 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005613 return;
5614 }
5615
5616 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5617
5618 if (control->poll) {
5619 l2cap_pass_to_tx(chan, control);
5620
5621 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5622 l2cap_retransmit(chan, control);
5623 l2cap_ertm_send(chan);
5624
5625 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5626 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5627 chan->srej_save_reqseq = control->reqseq;
5628 }
5629 } else {
5630 l2cap_pass_to_tx_fbit(chan, control);
5631
5632 if (control->final) {
5633 if (chan->srej_save_reqseq != control->reqseq ||
5634 !test_and_clear_bit(CONN_SREJ_ACT,
5635 &chan->conn_state))
5636 l2cap_retransmit(chan, control);
5637 } else {
5638 l2cap_retransmit(chan, control);
5639 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5640 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5641 chan->srej_save_reqseq = control->reqseq;
5642 }
5643 }
5644 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005645}
5646
5647static void l2cap_handle_rej(struct l2cap_chan *chan,
5648 struct l2cap_ctrl *control)
5649{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005650 struct sk_buff *skb;
5651
5652 BT_DBG("chan %p, control %p", chan, control);
5653
5654 if (control->reqseq == chan->next_tx_seq) {
5655 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005656 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005657 return;
5658 }
5659
5660 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5661
5662 if (chan->max_tx && skb &&
5663 bt_cb(skb)->control.retries >= chan->max_tx) {
5664 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005665 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005666 return;
5667 }
5668
5669 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5670
5671 l2cap_pass_to_tx(chan, control);
5672
5673 if (control->final) {
5674 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5675 l2cap_retransmit_all(chan, control);
5676 } else {
5677 l2cap_retransmit_all(chan, control);
5678 l2cap_ertm_send(chan);
5679 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5680 set_bit(CONN_REJ_ACT, &chan->conn_state);
5681 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005682}
5683
Mat Martineau4b51dae92012-05-17 20:53:37 -07005684static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5685{
5686 BT_DBG("chan %p, txseq %d", chan, txseq);
5687
5688 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5689 chan->expected_tx_seq);
5690
5691 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5692 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005693 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005694 /* See notes below regarding "double poll" and
5695 * invalid packets.
5696 */
5697 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5698 BT_DBG("Invalid/Ignore - after SREJ");
5699 return L2CAP_TXSEQ_INVALID_IGNORE;
5700 } else {
5701 BT_DBG("Invalid - in window after SREJ sent");
5702 return L2CAP_TXSEQ_INVALID;
5703 }
5704 }
5705
5706 if (chan->srej_list.head == txseq) {
5707 BT_DBG("Expected SREJ");
5708 return L2CAP_TXSEQ_EXPECTED_SREJ;
5709 }
5710
5711 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5712 BT_DBG("Duplicate SREJ - txseq already stored");
5713 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5714 }
5715
5716 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5717 BT_DBG("Unexpected SREJ - not requested");
5718 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5719 }
5720 }
5721
5722 if (chan->expected_tx_seq == txseq) {
5723 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5724 chan->tx_win) {
5725 BT_DBG("Invalid - txseq outside tx window");
5726 return L2CAP_TXSEQ_INVALID;
5727 } else {
5728 BT_DBG("Expected");
5729 return L2CAP_TXSEQ_EXPECTED;
5730 }
5731 }
5732
5733 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01005734 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005735 BT_DBG("Duplicate - expected_tx_seq later than txseq");
5736 return L2CAP_TXSEQ_DUPLICATE;
5737 }
5738
5739 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
5740 /* A source of invalid packets is a "double poll" condition,
5741 * where delays cause us to send multiple poll packets. If
5742 * the remote stack receives and processes both polls,
5743 * sequence numbers can wrap around in such a way that a
5744 * resent frame has a sequence number that looks like new data
5745 * with a sequence gap. This would trigger an erroneous SREJ
5746 * request.
5747 *
5748 * Fortunately, this is impossible with a tx window that's
5749 * less than half of the maximum sequence number, which allows
5750 * invalid frames to be safely ignored.
5751 *
5752 * With tx window sizes greater than half of the tx window
5753 * maximum, the frame is invalid and cannot be ignored. This
5754 * causes a disconnect.
5755 */
5756
5757 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5758 BT_DBG("Invalid/Ignore - txseq outside tx window");
5759 return L2CAP_TXSEQ_INVALID_IGNORE;
5760 } else {
5761 BT_DBG("Invalid - txseq outside tx window");
5762 return L2CAP_TXSEQ_INVALID;
5763 }
5764 } else {
5765 BT_DBG("Unexpected - txseq indicates missing frames");
5766 return L2CAP_TXSEQ_UNEXPECTED;
5767 }
5768}
5769
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005770static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5771 struct l2cap_ctrl *control,
5772 struct sk_buff *skb, u8 event)
5773{
5774 int err = 0;
5775 bool skb_in_use = 0;
5776
5777 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5778 event);
5779
5780 switch (event) {
5781 case L2CAP_EV_RECV_IFRAME:
5782 switch (l2cap_classify_txseq(chan, control->txseq)) {
5783 case L2CAP_TXSEQ_EXPECTED:
5784 l2cap_pass_to_tx(chan, control);
5785
5786 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5787 BT_DBG("Busy, discarding expected seq %d",
5788 control->txseq);
5789 break;
5790 }
5791
5792 chan->expected_tx_seq = __next_seq(chan,
5793 control->txseq);
5794
5795 chan->buffer_seq = chan->expected_tx_seq;
5796 skb_in_use = 1;
5797
5798 err = l2cap_reassemble_sdu(chan, skb, control);
5799 if (err)
5800 break;
5801
5802 if (control->final) {
5803 if (!test_and_clear_bit(CONN_REJ_ACT,
5804 &chan->conn_state)) {
5805 control->final = 0;
5806 l2cap_retransmit_all(chan, control);
5807 l2cap_ertm_send(chan);
5808 }
5809 }
5810
5811 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5812 l2cap_send_ack(chan);
5813 break;
5814 case L2CAP_TXSEQ_UNEXPECTED:
5815 l2cap_pass_to_tx(chan, control);
5816
5817 /* Can't issue SREJ frames in the local busy state.
5818 * Drop this frame, it will be seen as missing
5819 * when local busy is exited.
5820 */
5821 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5822 BT_DBG("Busy, discarding unexpected seq %d",
5823 control->txseq);
5824 break;
5825 }
5826
5827 /* There was a gap in the sequence, so an SREJ
5828 * must be sent for each missing frame. The
5829 * current frame is stored for later use.
5830 */
5831 skb_queue_tail(&chan->srej_q, skb);
5832 skb_in_use = 1;
5833 BT_DBG("Queued %p (queue len %d)", skb,
5834 skb_queue_len(&chan->srej_q));
5835
5836 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5837 l2cap_seq_list_clear(&chan->srej_list);
5838 l2cap_send_srej(chan, control->txseq);
5839
5840 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5841 break;
5842 case L2CAP_TXSEQ_DUPLICATE:
5843 l2cap_pass_to_tx(chan, control);
5844 break;
5845 case L2CAP_TXSEQ_INVALID_IGNORE:
5846 break;
5847 case L2CAP_TXSEQ_INVALID:
5848 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005849 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005850 break;
5851 }
5852 break;
5853 case L2CAP_EV_RECV_RR:
5854 l2cap_pass_to_tx(chan, control);
5855 if (control->final) {
5856 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5857
Mat Martineaue6a3ee62012-10-23 15:24:22 -07005858 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
5859 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005860 control->final = 0;
5861 l2cap_retransmit_all(chan, control);
5862 }
5863
5864 l2cap_ertm_send(chan);
5865 } else if (control->poll) {
5866 l2cap_send_i_or_rr_or_rnr(chan);
5867 } else {
5868 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5869 &chan->conn_state) &&
5870 chan->unacked_frames)
5871 __set_retrans_timer(chan);
5872
5873 l2cap_ertm_send(chan);
5874 }
5875 break;
5876 case L2CAP_EV_RECV_RNR:
5877 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5878 l2cap_pass_to_tx(chan, control);
5879 if (control && control->poll) {
5880 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5881 l2cap_send_rr_or_rnr(chan, 0);
5882 }
5883 __clear_retrans_timer(chan);
5884 l2cap_seq_list_clear(&chan->retrans_list);
5885 break;
5886 case L2CAP_EV_RECV_REJ:
5887 l2cap_handle_rej(chan, control);
5888 break;
5889 case L2CAP_EV_RECV_SREJ:
5890 l2cap_handle_srej(chan, control);
5891 break;
5892 default:
5893 break;
5894 }
5895
5896 if (skb && !skb_in_use) {
5897 BT_DBG("Freeing %p", skb);
5898 kfree_skb(skb);
5899 }
5900
5901 return err;
5902}
5903
5904static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5905 struct l2cap_ctrl *control,
5906 struct sk_buff *skb, u8 event)
5907{
5908 int err = 0;
5909 u16 txseq = control->txseq;
5910 bool skb_in_use = 0;
5911
5912 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5913 event);
5914
5915 switch (event) {
5916 case L2CAP_EV_RECV_IFRAME:
5917 switch (l2cap_classify_txseq(chan, txseq)) {
5918 case L2CAP_TXSEQ_EXPECTED:
5919 /* Keep frame for reassembly later */
5920 l2cap_pass_to_tx(chan, control);
5921 skb_queue_tail(&chan->srej_q, skb);
5922 skb_in_use = 1;
5923 BT_DBG("Queued %p (queue len %d)", skb,
5924 skb_queue_len(&chan->srej_q));
5925
5926 chan->expected_tx_seq = __next_seq(chan, txseq);
5927 break;
5928 case L2CAP_TXSEQ_EXPECTED_SREJ:
5929 l2cap_seq_list_pop(&chan->srej_list);
5930
5931 l2cap_pass_to_tx(chan, control);
5932 skb_queue_tail(&chan->srej_q, skb);
5933 skb_in_use = 1;
5934 BT_DBG("Queued %p (queue len %d)", skb,
5935 skb_queue_len(&chan->srej_q));
5936
5937 err = l2cap_rx_queued_iframes(chan);
5938 if (err)
5939 break;
5940
5941 break;
5942 case L2CAP_TXSEQ_UNEXPECTED:
5943 /* Got a frame that can't be reassembled yet.
5944 * Save it for later, and send SREJs to cover
5945 * the missing frames.
5946 */
5947 skb_queue_tail(&chan->srej_q, skb);
5948 skb_in_use = 1;
5949 BT_DBG("Queued %p (queue len %d)", skb,
5950 skb_queue_len(&chan->srej_q));
5951
5952 l2cap_pass_to_tx(chan, control);
5953 l2cap_send_srej(chan, control->txseq);
5954 break;
5955 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
5956 /* This frame was requested with an SREJ, but
5957 * some expected retransmitted frames are
5958 * missing. Request retransmission of missing
5959 * SREJ'd frames.
5960 */
5961 skb_queue_tail(&chan->srej_q, skb);
5962 skb_in_use = 1;
5963 BT_DBG("Queued %p (queue len %d)", skb,
5964 skb_queue_len(&chan->srej_q));
5965
5966 l2cap_pass_to_tx(chan, control);
5967 l2cap_send_srej_list(chan, control->txseq);
5968 break;
5969 case L2CAP_TXSEQ_DUPLICATE_SREJ:
5970 /* We've already queued this frame. Drop this copy. */
5971 l2cap_pass_to_tx(chan, control);
5972 break;
5973 case L2CAP_TXSEQ_DUPLICATE:
5974 /* Expecting a later sequence number, so this frame
5975 * was already received. Ignore it completely.
5976 */
5977 break;
5978 case L2CAP_TXSEQ_INVALID_IGNORE:
5979 break;
5980 case L2CAP_TXSEQ_INVALID:
5981 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005982 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005983 break;
5984 }
5985 break;
5986 case L2CAP_EV_RECV_RR:
5987 l2cap_pass_to_tx(chan, control);
5988 if (control->final) {
5989 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5990
5991 if (!test_and_clear_bit(CONN_REJ_ACT,
5992 &chan->conn_state)) {
5993 control->final = 0;
5994 l2cap_retransmit_all(chan, control);
5995 }
5996
5997 l2cap_ertm_send(chan);
5998 } else if (control->poll) {
5999 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6000 &chan->conn_state) &&
6001 chan->unacked_frames) {
6002 __set_retrans_timer(chan);
6003 }
6004
6005 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6006 l2cap_send_srej_tail(chan);
6007 } else {
6008 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6009 &chan->conn_state) &&
6010 chan->unacked_frames)
6011 __set_retrans_timer(chan);
6012
6013 l2cap_send_ack(chan);
6014 }
6015 break;
6016 case L2CAP_EV_RECV_RNR:
6017 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6018 l2cap_pass_to_tx(chan, control);
6019 if (control->poll) {
6020 l2cap_send_srej_tail(chan);
6021 } else {
6022 struct l2cap_ctrl rr_control;
6023 memset(&rr_control, 0, sizeof(rr_control));
6024 rr_control.sframe = 1;
6025 rr_control.super = L2CAP_SUPER_RR;
6026 rr_control.reqseq = chan->buffer_seq;
6027 l2cap_send_sframe(chan, &rr_control);
6028 }
6029
6030 break;
6031 case L2CAP_EV_RECV_REJ:
6032 l2cap_handle_rej(chan, control);
6033 break;
6034 case L2CAP_EV_RECV_SREJ:
6035 l2cap_handle_srej(chan, control);
6036 break;
6037 }
6038
6039 if (skb && !skb_in_use) {
6040 BT_DBG("Freeing %p", skb);
6041 kfree_skb(skb);
6042 }
6043
6044 return err;
6045}
6046
Mat Martineau32b32732012-10-23 15:24:11 -07006047static int l2cap_finish_move(struct l2cap_chan *chan)
6048{
6049 BT_DBG("chan %p", chan);
6050
6051 chan->rx_state = L2CAP_RX_STATE_RECV;
6052
6053 if (chan->hs_hcon)
6054 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6055 else
6056 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6057
6058 return l2cap_resegment(chan);
6059}
6060
6061static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6062 struct l2cap_ctrl *control,
6063 struct sk_buff *skb, u8 event)
6064{
6065 int err;
6066
6067 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6068 event);
6069
6070 if (!control->poll)
6071 return -EPROTO;
6072
6073 l2cap_process_reqseq(chan, control->reqseq);
6074
6075 if (!skb_queue_empty(&chan->tx_q))
6076 chan->tx_send_head = skb_peek(&chan->tx_q);
6077 else
6078 chan->tx_send_head = NULL;
6079
6080 /* Rewind next_tx_seq to the point expected
6081 * by the receiver.
6082 */
6083 chan->next_tx_seq = control->reqseq;
6084 chan->unacked_frames = 0;
6085
6086 err = l2cap_finish_move(chan);
6087 if (err)
6088 return err;
6089
6090 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6091 l2cap_send_i_or_rr_or_rnr(chan);
6092
6093 if (event == L2CAP_EV_RECV_IFRAME)
6094 return -EPROTO;
6095
6096 return l2cap_rx_state_recv(chan, control, NULL, event);
6097}
6098
6099static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6100 struct l2cap_ctrl *control,
6101 struct sk_buff *skb, u8 event)
6102{
6103 int err;
6104
6105 if (!control->final)
6106 return -EPROTO;
6107
6108 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6109
6110 chan->rx_state = L2CAP_RX_STATE_RECV;
6111 l2cap_process_reqseq(chan, control->reqseq);
6112
6113 if (!skb_queue_empty(&chan->tx_q))
6114 chan->tx_send_head = skb_peek(&chan->tx_q);
6115 else
6116 chan->tx_send_head = NULL;
6117
6118 /* Rewind next_tx_seq to the point expected
6119 * by the receiver.
6120 */
6121 chan->next_tx_seq = control->reqseq;
6122 chan->unacked_frames = 0;
6123
6124 if (chan->hs_hcon)
6125 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6126 else
6127 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6128
6129 err = l2cap_resegment(chan);
6130
6131 if (!err)
6132 err = l2cap_rx_state_recv(chan, control, skb, event);
6133
6134 return err;
6135}
6136
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006137static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6138{
6139 /* Make sure reqseq is for a packet that has been sent but not acked */
6140 u16 unacked;
6141
6142 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6143 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6144}
6145
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006146static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6147 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006148{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006149 int err = 0;
6150
6151 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6152 control, skb, event, chan->rx_state);
6153
6154 if (__valid_reqseq(chan, control->reqseq)) {
6155 switch (chan->rx_state) {
6156 case L2CAP_RX_STATE_RECV:
6157 err = l2cap_rx_state_recv(chan, control, skb, event);
6158 break;
6159 case L2CAP_RX_STATE_SREJ_SENT:
6160 err = l2cap_rx_state_srej_sent(chan, control, skb,
6161 event);
6162 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006163 case L2CAP_RX_STATE_WAIT_P:
6164 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6165 break;
6166 case L2CAP_RX_STATE_WAIT_F:
6167 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6168 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006169 default:
6170 /* shut it down */
6171 break;
6172 }
6173 } else {
6174 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6175 control->reqseq, chan->next_tx_seq,
6176 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006177 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006178 }
6179
6180 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006181}
6182
6183static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6184 struct sk_buff *skb)
6185{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006186 int err = 0;
6187
6188 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6189 chan->rx_state);
6190
6191 if (l2cap_classify_txseq(chan, control->txseq) ==
6192 L2CAP_TXSEQ_EXPECTED) {
6193 l2cap_pass_to_tx(chan, control);
6194
6195 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6196 __next_seq(chan, chan->buffer_seq));
6197
6198 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6199
6200 l2cap_reassemble_sdu(chan, skb, control);
6201 } else {
6202 if (chan->sdu) {
6203 kfree_skb(chan->sdu);
6204 chan->sdu = NULL;
6205 }
6206 chan->sdu_last_frag = NULL;
6207 chan->sdu_len = 0;
6208
6209 if (skb) {
6210 BT_DBG("Freeing %p", skb);
6211 kfree_skb(skb);
6212 }
6213 }
6214
6215 chan->last_acked_seq = control->txseq;
6216 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6217
6218 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006219}
6220
6221static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6222{
6223 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6224 u16 len;
6225 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006226
Mat Martineaub76bbd62012-04-11 10:48:43 -07006227 __unpack_control(chan, skb);
6228
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006229 len = skb->len;
6230
6231 /*
6232 * We can just drop the corrupted I-frame here.
6233 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006234 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006235 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006236 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006237 goto drop;
6238
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006239 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006240 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006241
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006242 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006243 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006244
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006245 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006246 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006247 goto drop;
6248 }
6249
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006250 if (!control->sframe) {
6251 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006252
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006253 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6254 control->sar, control->reqseq, control->final,
6255 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006256
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006257 /* Validate F-bit - F=0 always valid, F=1 only
6258 * valid in TX WAIT_F
6259 */
6260 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006261 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006262
6263 if (chan->mode != L2CAP_MODE_STREAMING) {
6264 event = L2CAP_EV_RECV_IFRAME;
6265 err = l2cap_rx(chan, control, skb, event);
6266 } else {
6267 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006268 }
6269
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006270 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006271 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006272 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006273 const u8 rx_func_to_event[4] = {
6274 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6275 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6276 };
6277
6278 /* Only I-frames are expected in streaming mode */
6279 if (chan->mode == L2CAP_MODE_STREAMING)
6280 goto drop;
6281
6282 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6283 control->reqseq, control->final, control->poll,
6284 control->super);
6285
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006286 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006287 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006288 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006289 goto drop;
6290 }
6291
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006292 /* Validate F and P bits */
6293 if (control->final && (control->poll ||
6294 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6295 goto drop;
6296
6297 event = rx_func_to_event[control->super];
6298 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006299 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006300 }
6301
6302 return 0;
6303
6304drop:
6305 kfree_skb(skb);
6306 return 0;
6307}
6308
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006309static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6310 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006311{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006312 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006313
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006314 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006315 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006316 if (cid == L2CAP_CID_A2MP) {
6317 chan = a2mp_channel_create(conn, skb);
6318 if (!chan) {
6319 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006320 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006321 }
6322
6323 l2cap_chan_lock(chan);
6324 } else {
6325 BT_DBG("unknown cid 0x%4.4x", cid);
6326 /* Drop packet and return */
6327 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006328 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006329 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006330 }
6331
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006332 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006333
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006334 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006335 goto drop;
6336
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006337 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006338 case L2CAP_MODE_BASIC:
6339 /* If socket recv buffers overflows we drop data here
6340 * which is *bad* because L2CAP has to be reliable.
6341 * But we don't have any other choice. L2CAP doesn't
6342 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006343
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006344 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006345 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006346
Gustavo Padovan80b98022012-05-27 22:27:51 -03006347 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006348 goto done;
6349 break;
6350
6351 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006352 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006353 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006354 goto done;
6355
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006356 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006357 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006358 break;
6359 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006360
6361drop:
6362 kfree_skb(skb);
6363
6364done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006365 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006366}
6367
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006368static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6369 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006370{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006371 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006372
Ido Yarivc2287682012-04-20 15:46:07 -03006373 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006374 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006375 goto drop;
6376
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006377 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006378
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006379 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006380 goto drop;
6381
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006382 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006383 goto drop;
6384
Gustavo Padovan80b98022012-05-27 22:27:51 -03006385 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006386 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006387
6388drop:
6389 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006390}
6391
Marcel Holtmann72f78352013-04-23 00:59:00 -07006392static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006393 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006394{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006395 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006396
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006397 chan = l2cap_global_chan_by_scid(0, L2CAP_CID_ATT,
Marcel Holtmann72f78352013-04-23 00:59:00 -07006398 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006399 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006400 goto drop;
6401
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006402 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006403
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006404 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006405 goto drop;
6406
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006407 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006408 goto drop;
6409
Gustavo Padovan80b98022012-05-27 22:27:51 -03006410 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006411 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006412
6413drop:
6414 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006415}
6416
Linus Torvalds1da177e2005-04-16 15:20:36 -07006417static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6418{
6419 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006420 u16 cid, len;
6421 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006422
6423 skb_pull(skb, L2CAP_HDR_SIZE);
6424 cid = __le16_to_cpu(lh->cid);
6425 len = __le16_to_cpu(lh->len);
6426
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006427 if (len != skb->len) {
6428 kfree_skb(skb);
6429 return;
6430 }
6431
Linus Torvalds1da177e2005-04-16 15:20:36 -07006432 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6433
6434 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02006435 case L2CAP_CID_LE_SIGNALING:
Johan Hedbergc5623552013-04-29 19:35:33 +03006436 l2cap_le_sig_channel(conn, skb);
6437 break;
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006438 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006439 l2cap_sig_channel(conn, skb);
6440 break;
6441
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006442 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006443 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006444 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006445 l2cap_conless_channel(conn, psm, skb);
6446 break;
6447
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006448 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006449 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006450 break;
6451
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006452 case L2CAP_CID_SMP:
6453 if (smp_sig_channel(conn, skb))
6454 l2cap_conn_del(conn->hcon, EACCES);
6455 break;
6456
Linus Torvalds1da177e2005-04-16 15:20:36 -07006457 default:
6458 l2cap_data_channel(conn, cid, skb);
6459 break;
6460 }
6461}
6462
6463/* ---- L2CAP interface with lower layer (HCI) ---- */
6464
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006465int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006466{
6467 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006468 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006469
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006470 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006471
6472 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006473 read_lock(&chan_list_lock);
6474 list_for_each_entry(c, &chan_list, global_l) {
6475 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006476
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006477 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006478 continue;
6479
6480 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006481 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006482 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006483 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006484 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006485 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
6486 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006487 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006488 lm2 |= HCI_LM_MASTER;
6489 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006490 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006491 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006492
6493 return exact ? lm1 : lm2;
6494}
6495
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006496void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006497{
Marcel Holtmann01394182006-07-03 10:02:46 +02006498 struct l2cap_conn *conn;
6499
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006500 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006501
Linus Torvalds1da177e2005-04-16 15:20:36 -07006502 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03006503 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006504 if (conn)
6505 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006506 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006507 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006508 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006509}
6510
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006511int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006512{
6513 struct l2cap_conn *conn = hcon->l2cap_data;
6514
6515 BT_DBG("hcon %p", hcon);
6516
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006517 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006518 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006519 return conn->disc_reason;
6520}
6521
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006522void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006523{
6524 BT_DBG("hcon %p reason %d", hcon, reason);
6525
Joe Perchese1750722011-06-29 18:18:29 -07006526 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006527}
6528
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006529static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006530{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006531 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006532 return;
6533
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006534 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006535 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006536 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006537 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006538 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006539 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006540 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006541 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006542 }
6543}
6544
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006545int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006546{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006547 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006548 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006549
Marcel Holtmann01394182006-07-03 10:02:46 +02006550 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006551 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006552
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006553 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006554
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006555 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306556 if (!status && encrypt)
6557 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006558 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006559 }
6560
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006561 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006562
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006563 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006564 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006565
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006566 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6567 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006568
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006569 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6570 l2cap_chan_unlock(chan);
6571 continue;
6572 }
6573
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006574 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006575 if (!status && encrypt) {
6576 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006577 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006578 }
6579
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006580 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006581 continue;
6582 }
6583
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006584 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006585 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006586 continue;
6587 }
6588
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006589 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006590 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03006591 struct sock *sk = chan->sk;
6592
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006593 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03006594 sk->sk_state_change(sk);
6595
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006596 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006597 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006598 continue;
6599 }
6600
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006601 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006602 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006603 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006604 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006605 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006606 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006607 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006608 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006609 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006610 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006611
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006612 lock_sock(sk);
6613
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006614 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006615 if (test_bit(BT_SK_DEFER_SETUP,
6616 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006617 res = L2CAP_CR_PEND;
6618 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006619 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006620 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006621 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006622 res = L2CAP_CR_SUCCESS;
6623 stat = L2CAP_CS_NO_INFO;
6624 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006625 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006626 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006627 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006628 res = L2CAP_CR_SEC_BLOCK;
6629 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006630 }
6631
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006632 release_sock(sk);
6633
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006634 rsp.scid = cpu_to_le16(chan->dcid);
6635 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006636 rsp.result = cpu_to_le16(res);
6637 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006638 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006639 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006640
6641 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6642 res == L2CAP_CR_SUCCESS) {
6643 char buf[128];
6644 set_bit(CONF_REQ_SENT, &chan->conf_state);
6645 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6646 L2CAP_CONF_REQ,
6647 l2cap_build_conf_req(chan, buf),
6648 buf);
6649 chan->num_conf_req++;
6650 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006651 }
6652
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006653 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006654 }
6655
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006656 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006657
Linus Torvalds1da177e2005-04-16 15:20:36 -07006658 return 0;
6659}
6660
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006661int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006662{
6663 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006664 struct l2cap_hdr *hdr;
6665 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006666
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006667 /* For AMP controller do not create l2cap conn */
6668 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6669 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006670
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006671 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03006672 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006673
6674 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006675 goto drop;
6676
6677 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6678
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006679 switch (flags) {
6680 case ACL_START:
6681 case ACL_START_NO_FLUSH:
6682 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006683 if (conn->rx_len) {
6684 BT_ERR("Unexpected start frame (len %d)", skb->len);
6685 kfree_skb(conn->rx_skb);
6686 conn->rx_skb = NULL;
6687 conn->rx_len = 0;
6688 l2cap_conn_unreliable(conn, ECOMM);
6689 }
6690
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006691 /* Start fragment always begin with Basic L2CAP header */
6692 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006693 BT_ERR("Frame is too short (len %d)", skb->len);
6694 l2cap_conn_unreliable(conn, ECOMM);
6695 goto drop;
6696 }
6697
6698 hdr = (struct l2cap_hdr *) skb->data;
6699 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6700
6701 if (len == skb->len) {
6702 /* Complete frame received */
6703 l2cap_recv_frame(conn, skb);
6704 return 0;
6705 }
6706
6707 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6708
6709 if (skb->len > len) {
6710 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006711 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006712 l2cap_conn_unreliable(conn, ECOMM);
6713 goto drop;
6714 }
6715
6716 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006717 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006718 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006719 goto drop;
6720
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006721 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006722 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006723 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006724 break;
6725
6726 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006727 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6728
6729 if (!conn->rx_len) {
6730 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6731 l2cap_conn_unreliable(conn, ECOMM);
6732 goto drop;
6733 }
6734
6735 if (skb->len > conn->rx_len) {
6736 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006737 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006738 kfree_skb(conn->rx_skb);
6739 conn->rx_skb = NULL;
6740 conn->rx_len = 0;
6741 l2cap_conn_unreliable(conn, ECOMM);
6742 goto drop;
6743 }
6744
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006745 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006746 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006747 conn->rx_len -= skb->len;
6748
6749 if (!conn->rx_len) {
6750 /* Complete frame received */
6751 l2cap_recv_frame(conn, conn->rx_skb);
6752 conn->rx_skb = NULL;
6753 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006754 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006755 }
6756
6757drop:
6758 kfree_skb(skb);
6759 return 0;
6760}
6761
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006762static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006763{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006764 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006765
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006766 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006767
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006768 list_for_each_entry(c, &chan_list, global_l) {
6769 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006770
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006771 seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
6772 &bt_sk(sk)->src, &bt_sk(sk)->dst,
6773 c->state, __le16_to_cpu(c->psm),
6774 c->scid, c->dcid, c->imtu, c->omtu,
6775 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006776 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006777
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006778 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006779
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006780 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006781}
6782
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006783static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6784{
6785 return single_open(file, l2cap_debugfs_show, inode->i_private);
6786}
6787
6788static const struct file_operations l2cap_debugfs_fops = {
6789 .open = l2cap_debugfs_open,
6790 .read = seq_read,
6791 .llseek = seq_lseek,
6792 .release = single_release,
6793};
6794
6795static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006796
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006797int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006798{
6799 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006800
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006801 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006802 if (err < 0)
6803 return err;
6804
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006805 if (bt_debugfs) {
Gustavo Padovan2d792812012-10-06 10:07:01 +01006806 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6807 NULL, &l2cap_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006808 if (!l2cap_debugfs)
6809 BT_ERR("Failed to create L2CAP debug file");
6810 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006811
Linus Torvalds1da177e2005-04-16 15:20:36 -07006812 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006813}
6814
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006815void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006816{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006817 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006818 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006819}
6820
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006821module_param(disable_ertm, bool, 0644);
6822MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");