blob: 2ff35a25374a5d585625ea05a84a70cb2c0223a7 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
Gustavo F. Padovance5706b2010-07-13 11:57:11 -03004 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
Gustavo F. Padovan5d8868f2010-07-16 16:18:39 -03005 Copyright (C) 2010 Google Inc.
Gustavo F. Padovan590051d2011-12-18 13:39:33 -02006 Copyright (C) 2011 ProFUSION Embedded Systems
Mat Martineau422e9252012-04-27 16:50:55 -07007 Copyright (c) 2012 Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07008
9 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License version 2 as
13 published by the Free Software Foundation;
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
18 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090019 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090024 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
25 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070026 SOFTWARE IS DISCLAIMED.
27*/
28
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020029/* Bluetooth L2CAP core. */
Linus Torvalds1da177e2005-04-16 15:20:36 -070030
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/module.h>
32
Marcel Holtmannaef7d972010-03-21 05:27:45 +010033#include <linux/debugfs.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030034#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36#include <net/bluetooth/bluetooth.h>
37#include <net/bluetooth/hci_core.h>
38#include <net/bluetooth/l2cap.h>
Anderson Brigliab501d6a2011-06-07 18:46:31 -030039#include <net/bluetooth/smp.h>
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +030040#include <net/bluetooth/a2mp.h>
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +020041#include <net/bluetooth/amp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
Mat Martineaud1de6d42012-05-17 20:53:55 -070043bool disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020044
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070045static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Mat Martineau50a147c2011-11-02 16:18:34 -070046static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070047
Johannes Bergb5ad8b72011-06-01 08:54:45 +020048static LIST_HEAD(chan_list);
49static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
Linus Torvalds1da177e2005-04-16 15:20:36 -070051static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +010052 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030053static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
Gustavo Padovan2d792812012-10-06 10:07:01 +010054 void *data);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -030055static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +020056static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Gustavo Padovand6603662012-05-21 13:58:22 -030058static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
Gustavo Padovan2d792812012-10-06 10:07:01 +010059 struct sk_buff_head *skbs, u8 event);
Mat Martineau608bcc62012-05-17 20:53:32 -070060
Marcel Holtmann01394182006-07-03 10:02:46 +020061/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030062
Gustavo Padovan2d792812012-10-06 10:07:01 +010063static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
64 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020065{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020066 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030067
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020068 list_for_each_entry(c, &conn->chan_l, list) {
69 if (c->dcid == cid)
70 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020071 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020072 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020073}
74
Gustavo Padovan2d792812012-10-06 10:07:01 +010075static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
76 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020077{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020078 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030079
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020080 list_for_each_entry(c, &conn->chan_l, list) {
81 if (c->scid == cid)
82 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020083 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020084 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020085}
86
87/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -070088 * Returns locked channel. */
Gustavo Padovan2d792812012-10-06 10:07:01 +010089static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
90 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020091{
Gustavo F. Padovan48454072011-03-25 00:22:30 -030092 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030093
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020094 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030095 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -070096 if (c)
97 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020098 mutex_unlock(&conn->chan_lock);
99
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300100 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200101}
102
Mat Martineaub1a130b2012-10-23 15:24:09 -0700103/* Find channel with given DCID.
104 * Returns locked channel.
105 */
106static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
107 u16 cid)
108{
109 struct l2cap_chan *c;
110
111 mutex_lock(&conn->chan_lock);
112 c = __l2cap_get_chan_by_dcid(conn, cid);
113 if (c)
114 l2cap_chan_lock(c);
115 mutex_unlock(&conn->chan_lock);
116
117 return c;
118}
119
Gustavo Padovan2d792812012-10-06 10:07:01 +0100120static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
121 u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200122{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200123 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300124
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200125 list_for_each_entry(c, &conn->chan_l, list) {
126 if (c->ident == ident)
127 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200128 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200129 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200130}
131
Mat Martineau5b155ef2012-10-23 15:24:14 -0700132static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
133 u8 ident)
134{
135 struct l2cap_chan *c;
136
137 mutex_lock(&conn->chan_lock);
138 c = __l2cap_get_chan_by_ident(conn, ident);
139 if (c)
140 l2cap_chan_lock(c);
141 mutex_unlock(&conn->chan_lock);
142
143 return c;
144}
145
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300146static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300147{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300148 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300149
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300150 list_for_each_entry(c, &chan_list, global_l) {
151 if (c->sport == psm && !bacmp(&bt_sk(c->sk)->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100152 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300153 }
Szymon Janc250938c2011-11-16 09:32:22 +0100154 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300155}
156
157int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
158{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300159 int err;
160
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200161 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300162
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300163 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300164 err = -EADDRINUSE;
165 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300166 }
167
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300168 if (psm) {
169 chan->psm = psm;
170 chan->sport = psm;
171 err = 0;
172 } else {
173 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300174
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300175 err = -EINVAL;
176 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300177 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300178 chan->psm = cpu_to_le16(p);
179 chan->sport = cpu_to_le16(p);
180 err = 0;
181 break;
182 }
183 }
184
185done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200186 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300187 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300188}
189
190int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
191{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200192 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300193
194 chan->scid = scid;
195
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200196 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300197
198 return 0;
199}
200
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300201static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200202{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300203 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200204
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300205 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300206 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200207 return cid;
208 }
209
210 return 0;
211}
212
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200213static void __l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300214{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200215 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100216 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200217
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300218 chan->state = state;
Gustavo Padovan80b98022012-05-27 22:27:51 -0300219 chan->ops->state_change(chan, state);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300220}
221
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200222static void l2cap_state_change(struct l2cap_chan *chan, int state)
223{
224 struct sock *sk = chan->sk;
225
226 lock_sock(sk);
227 __l2cap_state_change(chan, state);
228 release_sock(sk);
229}
230
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200231static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err)
232{
233 struct sock *sk = chan->sk;
234
235 sk->sk_err = err;
236}
237
238static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
239{
240 struct sock *sk = chan->sk;
241
242 lock_sock(sk);
243 __l2cap_chan_set_err(chan, err);
244 release_sock(sk);
245}
246
Mat Martineau4239d162012-05-17 20:53:49 -0700247static void __set_retrans_timer(struct l2cap_chan *chan)
248{
249 if (!delayed_work_pending(&chan->monitor_timer) &&
250 chan->retrans_timeout) {
251 l2cap_set_timer(chan, &chan->retrans_timer,
252 msecs_to_jiffies(chan->retrans_timeout));
253 }
254}
255
256static void __set_monitor_timer(struct l2cap_chan *chan)
257{
258 __clear_retrans_timer(chan);
259 if (chan->monitor_timeout) {
260 l2cap_set_timer(chan, &chan->monitor_timer,
261 msecs_to_jiffies(chan->monitor_timeout));
262 }
263}
264
Mat Martineau608bcc62012-05-17 20:53:32 -0700265static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
266 u16 seq)
267{
268 struct sk_buff *skb;
269
270 skb_queue_walk(head, skb) {
271 if (bt_cb(skb)->control.txseq == seq)
272 return skb;
273 }
274
275 return NULL;
276}
277
Mat Martineau3c588192012-04-11 10:48:42 -0700278/* ---- L2CAP sequence number lists ---- */
279
280/* For ERTM, ordered lists of sequence numbers must be tracked for
281 * SREJ requests that are received and for frames that are to be
282 * retransmitted. These seq_list functions implement a singly-linked
283 * list in an array, where membership in the list can also be checked
284 * in constant time. Items can also be added to the tail of the list
285 * and removed from the head in constant time, without further memory
286 * allocs or frees.
287 */
288
289static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
290{
291 size_t alloc_size, i;
292
293 /* Allocated size is a power of 2 to map sequence numbers
294 * (which may be up to 14 bits) in to a smaller array that is
295 * sized for the negotiated ERTM transmit windows.
296 */
297 alloc_size = roundup_pow_of_two(size);
298
299 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
300 if (!seq_list->list)
301 return -ENOMEM;
302
303 seq_list->mask = alloc_size - 1;
304 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
305 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
306 for (i = 0; i < alloc_size; i++)
307 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
308
309 return 0;
310}
311
312static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
313{
314 kfree(seq_list->list);
315}
316
317static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
318 u16 seq)
319{
320 /* Constant-time check for list membership */
321 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
322}
323
324static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
325{
326 u16 mask = seq_list->mask;
327
328 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
329 /* In case someone tries to pop the head of an empty list */
330 return L2CAP_SEQ_LIST_CLEAR;
331 } else if (seq_list->head == seq) {
332 /* Head can be removed in constant time */
333 seq_list->head = seq_list->list[seq & mask];
334 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
335
336 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
337 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
338 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
339 }
340 } else {
341 /* Walk the list to find the sequence number */
342 u16 prev = seq_list->head;
343 while (seq_list->list[prev & mask] != seq) {
344 prev = seq_list->list[prev & mask];
345 if (prev == L2CAP_SEQ_LIST_TAIL)
346 return L2CAP_SEQ_LIST_CLEAR;
347 }
348
349 /* Unlink the number from the list and clear it */
350 seq_list->list[prev & mask] = seq_list->list[seq & mask];
351 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
352 if (seq_list->tail == seq)
353 seq_list->tail = prev;
354 }
355 return seq;
356}
357
358static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
359{
360 /* Remove the head in constant time */
361 return l2cap_seq_list_remove(seq_list, seq_list->head);
362}
363
364static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
365{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300366 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700367
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300368 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
369 return;
370
371 for (i = 0; i <= seq_list->mask; i++)
372 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
373
374 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
375 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700376}
377
378static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
379{
380 u16 mask = seq_list->mask;
381
382 /* All appends happen in constant time */
383
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300384 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
385 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700386
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300387 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
388 seq_list->head = seq;
389 else
390 seq_list->list[seq_list->tail & mask] = seq;
391
392 seq_list->tail = seq;
393 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700394}
395
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300396static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300397{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300398 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100399 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200400 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300401 int reason;
402
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200403 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300404
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200405 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200406 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300407
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300408 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300409 reason = ECONNREFUSED;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300410 else if (chan->state == BT_CONNECT &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100411 chan->sec_level != BT_SECURITY_SDP)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300412 reason = ECONNREFUSED;
413 else
414 reason = ETIMEDOUT;
415
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300416 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300417
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200418 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300419
Gustavo Padovan80b98022012-05-27 22:27:51 -0300420 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200421 mutex_unlock(&conn->chan_lock);
422
Ulisses Furquim371fd832011-12-21 20:02:36 -0200423 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300424}
425
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300426struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200427{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300428 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200429
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300430 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
431 if (!chan)
432 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200433
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200434 mutex_init(&chan->lock);
435
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200436 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300437 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200438 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300439
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300440 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300441
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300442 chan->state = BT_OPEN;
443
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530444 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300445
Mat Martineau28270112012-05-17 21:14:09 -0700446 /* This flag is cleared in l2cap_chan_ready() */
447 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
448
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300449 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100450
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300451 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200452}
453
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530454static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300455{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530456 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
457
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530458 BT_DBG("chan %p", chan);
459
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200460 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300461 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200462 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300463
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530464 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300465}
466
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530467void l2cap_chan_hold(struct l2cap_chan *c)
468{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530469 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530470
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530471 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530472}
473
474void l2cap_chan_put(struct l2cap_chan *c)
475{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530476 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530477
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530478 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530479}
480
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300481void l2cap_chan_set_defaults(struct l2cap_chan *chan)
482{
483 chan->fcs = L2CAP_FCS_CRC16;
484 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
485 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
486 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700487 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300488 chan->sec_level = BT_SECURITY_LOW;
489
490 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
491}
492
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300493void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200494{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300495 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200496 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200497
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200498 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100499
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300500 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200501
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200502 switch (chan->chan_type) {
503 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300504 if (conn->hcon->type == LE_LINK) {
505 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300506 chan->omtu = L2CAP_DEFAULT_MTU;
Johan Hedberg9f22398c2013-04-29 19:35:38 +0300507 if (chan->dcid == L2CAP_CID_ATT)
508 chan->scid = L2CAP_CID_ATT;
509 else
510 chan->scid = l2cap_alloc_cid(conn);
Ville Tervob62f3282011-02-10 22:38:50 -0300511 } else {
512 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300513 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300514 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300515 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200516 break;
517
518 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200519 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300520 chan->scid = L2CAP_CID_CONN_LESS;
521 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300522 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200523 break;
524
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300525 case L2CAP_CHAN_CONN_FIX_A2MP:
526 chan->scid = L2CAP_CID_A2MP;
527 chan->dcid = L2CAP_CID_A2MP;
528 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
529 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
530 break;
531
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200532 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200533 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300534 chan->scid = L2CAP_CID_SIGNALING;
535 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300536 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200537 }
538
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300539 chan->local_id = L2CAP_BESTEFFORT_ID;
540 chan->local_stype = L2CAP_SERV_BESTEFFORT;
541 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
542 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
543 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300544 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300545
Ulisses Furquim371fd832011-12-21 20:02:36 -0200546 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300547
Johan Hedberg5ee98912013-04-29 19:35:43 +0300548 hci_conn_hold(conn->hcon);
549
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200550 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200551}
552
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300553void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200554{
555 mutex_lock(&conn->chan_lock);
556 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200557 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200558}
559
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300560void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200561{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300562 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200563
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300564 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200565
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300566 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200567
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900568 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300569 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300570 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200571 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200572
Ulisses Furquim371fd832011-12-21 20:02:36 -0200573 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300574
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300575 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300576
577 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
David Herrmann76a68ba2013-04-06 20:28:37 +0200578 hci_conn_drop(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300579
580 if (mgr && mgr->bredr_chan == chan)
581 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200582 }
583
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200584 if (chan->hs_hchan) {
585 struct hci_chan *hs_hchan = chan->hs_hchan;
586
587 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
588 amp_disconnect_logical_link(hs_hchan);
589 }
590
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100591 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200592
Mat Martineau28270112012-05-17 21:14:09 -0700593 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300594 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300595
Gustavo Padovanee556f62012-05-18 20:22:38 -0300596 switch(chan->mode) {
597 case L2CAP_MODE_BASIC:
598 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300599
Gustavo Padovanee556f62012-05-18 20:22:38 -0300600 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300601 __clear_retrans_timer(chan);
602 __clear_monitor_timer(chan);
603 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300604
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300605 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300606
Mat Martineau3c588192012-04-11 10:48:42 -0700607 l2cap_seq_list_free(&chan->srej_list);
608 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300609
610 /* fall through */
611
612 case L2CAP_MODE_STREAMING:
613 skb_queue_purge(&chan->tx_q);
614 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300615 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300616
617 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200618}
619
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300620void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300621{
622 struct l2cap_conn *conn = chan->conn;
623 struct sock *sk = chan->sk;
624
Gustavo Padovan2d792812012-10-06 10:07:01 +0100625 BT_DBG("chan %p state %s sk %p", chan, state_to_string(chan->state),
626 sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300627
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300628 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300629 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100630 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300631 break;
632
633 case BT_CONNECTED:
634 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300635 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100636 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300637 __set_chan_timer(chan, sk->sk_sndtimeo);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200638 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300639 } else
640 l2cap_chan_del(chan, reason);
641 break;
642
643 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300644 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100645 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300646 struct l2cap_conn_rsp rsp;
647 __u16 result;
648
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300649 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300650 result = L2CAP_CR_SEC_BLOCK;
651 else
652 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300653 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300654
655 rsp.scid = cpu_to_le16(chan->dcid);
656 rsp.dcid = cpu_to_le16(chan->scid);
657 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300658 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300659 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100660 sizeof(rsp), &rsp);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300661 }
662
663 l2cap_chan_del(chan, reason);
664 break;
665
666 case BT_CONNECT:
667 case BT_DISCONN:
668 l2cap_chan_del(chan, reason);
669 break;
670
671 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100672 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300673 break;
674 }
675}
676
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300677static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530678{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300679 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300680 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530681 case BT_SECURITY_HIGH:
682 return HCI_AT_DEDICATED_BONDING_MITM;
683 case BT_SECURITY_MEDIUM:
684 return HCI_AT_DEDICATED_BONDING;
685 default:
686 return HCI_AT_NO_BONDING;
687 }
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +0300688 } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300689 if (chan->sec_level == BT_SECURITY_LOW)
690 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530691
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300692 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530693 return HCI_AT_NO_BONDING_MITM;
694 else
695 return HCI_AT_NO_BONDING;
696 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300697 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530698 case BT_SECURITY_HIGH:
699 return HCI_AT_GENERAL_BONDING_MITM;
700 case BT_SECURITY_MEDIUM:
701 return HCI_AT_GENERAL_BONDING;
702 default:
703 return HCI_AT_NO_BONDING;
704 }
705 }
706}
707
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200708/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200709int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200710{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300711 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100712 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200713
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300714 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100715
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300716 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200717}
718
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200719static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200720{
721 u8 id;
722
723 /* Get next available identificator.
724 * 1 - 128 are used by kernel.
725 * 129 - 199 are reserved.
726 * 200 - 254 are used by utilities like l2ping, etc.
727 */
728
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200729 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200730
731 if (++conn->tx_ident > 128)
732 conn->tx_ident = 1;
733
734 id = conn->tx_ident;
735
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200736 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200737
738 return id;
739}
740
Gustavo Padovan2d792812012-10-06 10:07:01 +0100741static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
742 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200743{
744 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200745 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200746
747 BT_DBG("code 0x%2.2x", code);
748
749 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300750 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200751
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200752 if (lmp_no_flush_capable(conn->hcon->hdev))
753 flags = ACL_START_NO_FLUSH;
754 else
755 flags = ACL_START;
756
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700757 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200758 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700759
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200760 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200761}
762
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700763static bool __chan_is_moving(struct l2cap_chan *chan)
764{
765 return chan->move_state != L2CAP_MOVE_STABLE &&
766 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
767}
768
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200769static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
770{
771 struct hci_conn *hcon = chan->conn->hcon;
772 u16 flags;
773
774 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100775 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200776
Mat Martineaud5f8a752012-10-23 15:24:18 -0700777 if (chan->hs_hcon && !__chan_is_moving(chan)) {
778 if (chan->hs_hchan)
779 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
780 else
781 kfree_skb(skb);
782
783 return;
784 }
785
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200786 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100787 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200788 flags = ACL_START_NO_FLUSH;
789 else
790 flags = ACL_START;
791
792 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
793 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794}
795
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700796static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
797{
798 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
799 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
800
801 if (enh & L2CAP_CTRL_FRAME_TYPE) {
802 /* S-Frame */
803 control->sframe = 1;
804 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
805 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
806
807 control->sar = 0;
808 control->txseq = 0;
809 } else {
810 /* I-Frame */
811 control->sframe = 0;
812 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
813 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
814
815 control->poll = 0;
816 control->super = 0;
817 }
818}
819
820static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
821{
822 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
823 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
824
825 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
826 /* S-Frame */
827 control->sframe = 1;
828 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
829 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
830
831 control->sar = 0;
832 control->txseq = 0;
833 } else {
834 /* I-Frame */
835 control->sframe = 0;
836 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
837 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
838
839 control->poll = 0;
840 control->super = 0;
841 }
842}
843
844static inline void __unpack_control(struct l2cap_chan *chan,
845 struct sk_buff *skb)
846{
847 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
848 __unpack_extended_control(get_unaligned_le32(skb->data),
849 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700850 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700851 } else {
852 __unpack_enhanced_control(get_unaligned_le16(skb->data),
853 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700854 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700855 }
856}
857
858static u32 __pack_extended_control(struct l2cap_ctrl *control)
859{
860 u32 packed;
861
862 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
863 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
864
865 if (control->sframe) {
866 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
867 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
868 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
869 } else {
870 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
871 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
872 }
873
874 return packed;
875}
876
877static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
878{
879 u16 packed;
880
881 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
882 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
883
884 if (control->sframe) {
885 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
886 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
887 packed |= L2CAP_CTRL_FRAME_TYPE;
888 } else {
889 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
890 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
891 }
892
893 return packed;
894}
895
896static inline void __pack_control(struct l2cap_chan *chan,
897 struct l2cap_ctrl *control,
898 struct sk_buff *skb)
899{
900 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
901 put_unaligned_le32(__pack_extended_control(control),
902 skb->data + L2CAP_HDR_SIZE);
903 } else {
904 put_unaligned_le16(__pack_enhanced_control(control),
905 skb->data + L2CAP_HDR_SIZE);
906 }
907}
908
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300909static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
910{
911 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
912 return L2CAP_EXT_HDR_SIZE;
913 else
914 return L2CAP_ENH_HDR_SIZE;
915}
916
Mat Martineaua67d7f62012-05-17 20:53:35 -0700917static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
918 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300919{
920 struct sk_buff *skb;
921 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300922 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300923
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300924 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300925 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300926
Mat Martineaua67d7f62012-05-17 20:53:35 -0700927 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300928
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300929 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700930 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300931
932 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300933 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300934 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300935
Mat Martineaua67d7f62012-05-17 20:53:35 -0700936 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
937 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
938 else
939 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300940
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300941 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700942 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300943 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300944 }
945
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200946 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700947 return skb;
948}
949
950static void l2cap_send_sframe(struct l2cap_chan *chan,
951 struct l2cap_ctrl *control)
952{
953 struct sk_buff *skb;
954 u32 control_field;
955
956 BT_DBG("chan %p, control %p", chan, control);
957
958 if (!control->sframe)
959 return;
960
Mat Martineaub99e13a2012-10-23 15:24:19 -0700961 if (__chan_is_moving(chan))
962 return;
963
Mat Martineaua67d7f62012-05-17 20:53:35 -0700964 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
965 !control->poll)
966 control->final = 1;
967
968 if (control->super == L2CAP_SUPER_RR)
969 clear_bit(CONN_RNR_SENT, &chan->conn_state);
970 else if (control->super == L2CAP_SUPER_RNR)
971 set_bit(CONN_RNR_SENT, &chan->conn_state);
972
973 if (control->super != L2CAP_SUPER_SREJ) {
974 chan->last_acked_seq = control->reqseq;
975 __clear_ack_timer(chan);
976 }
977
978 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
979 control->final, control->poll, control->super);
980
981 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
982 control_field = __pack_extended_control(control);
983 else
984 control_field = __pack_enhanced_control(control);
985
986 skb = l2cap_create_sframe_pdu(chan, control_field);
987 if (!IS_ERR(skb))
988 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300989}
990
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700991static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300992{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700993 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300994
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700995 BT_DBG("chan %p, poll %d", chan, poll);
996
997 memset(&control, 0, sizeof(control));
998 control.sframe = 1;
999 control.poll = poll;
1000
1001 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
1002 control.super = L2CAP_SUPER_RNR;
1003 else
1004 control.super = L2CAP_SUPER_RR;
1005
1006 control.reqseq = chan->buffer_seq;
1007 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001008}
1009
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001010static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001011{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001012 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001013}
1014
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001015static bool __amp_capable(struct l2cap_chan *chan)
1016{
1017 struct l2cap_conn *conn = chan->conn;
1018
1019 if (enable_hs &&
Andrei Emeltchenko5d054162012-11-29 17:46:05 +02001020 hci_amp_capable() &&
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001021 chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED &&
1022 conn->fixed_chan_mask & L2CAP_FC_A2MP)
1023 return true;
1024 else
1025 return false;
1026}
1027
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001028static bool l2cap_check_efs(struct l2cap_chan *chan)
1029{
1030 /* Check EFS parameters */
1031 return true;
1032}
1033
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001034void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001035{
1036 struct l2cap_conn *conn = chan->conn;
1037 struct l2cap_conn_req req;
1038
1039 req.scid = cpu_to_le16(chan->scid);
1040 req.psm = chan->psm;
1041
1042 chan->ident = l2cap_get_ident(conn);
1043
1044 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1045
1046 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1047}
1048
Mat Martineau8eb200b2012-10-23 15:24:17 -07001049static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1050{
1051 struct l2cap_create_chan_req req;
1052 req.scid = cpu_to_le16(chan->scid);
1053 req.psm = chan->psm;
1054 req.amp_id = amp_id;
1055
1056 chan->ident = l2cap_get_ident(chan->conn);
1057
1058 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1059 sizeof(req), &req);
1060}
1061
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001062static void l2cap_move_setup(struct l2cap_chan *chan)
1063{
1064 struct sk_buff *skb;
1065
1066 BT_DBG("chan %p", chan);
1067
1068 if (chan->mode != L2CAP_MODE_ERTM)
1069 return;
1070
1071 __clear_retrans_timer(chan);
1072 __clear_monitor_timer(chan);
1073 __clear_ack_timer(chan);
1074
1075 chan->retry_count = 0;
1076 skb_queue_walk(&chan->tx_q, skb) {
1077 if (bt_cb(skb)->control.retries)
1078 bt_cb(skb)->control.retries = 1;
1079 else
1080 break;
1081 }
1082
1083 chan->expected_tx_seq = chan->buffer_seq;
1084
1085 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1086 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1087 l2cap_seq_list_clear(&chan->retrans_list);
1088 l2cap_seq_list_clear(&chan->srej_list);
1089 skb_queue_purge(&chan->srej_q);
1090
1091 chan->tx_state = L2CAP_TX_STATE_XMIT;
1092 chan->rx_state = L2CAP_RX_STATE_MOVE;
1093
1094 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1095}
1096
Mat Martineau5f3847a2012-10-23 15:24:12 -07001097static void l2cap_move_done(struct l2cap_chan *chan)
1098{
1099 u8 move_role = chan->move_role;
1100 BT_DBG("chan %p", chan);
1101
1102 chan->move_state = L2CAP_MOVE_STABLE;
1103 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1104
1105 if (chan->mode != L2CAP_MODE_ERTM)
1106 return;
1107
1108 switch (move_role) {
1109 case L2CAP_MOVE_ROLE_INITIATOR:
1110 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1111 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1112 break;
1113 case L2CAP_MOVE_ROLE_RESPONDER:
1114 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1115 break;
1116 }
1117}
1118
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001119static void l2cap_chan_ready(struct l2cap_chan *chan)
1120{
Mat Martineau28270112012-05-17 21:14:09 -07001121 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001122 chan->conf_state = 0;
1123 __clear_chan_timer(chan);
1124
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001125 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001126
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001127 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001128}
1129
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001130static void l2cap_start_connection(struct l2cap_chan *chan)
1131{
1132 if (__amp_capable(chan)) {
1133 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1134 a2mp_discover_amp(chan);
1135 } else {
1136 l2cap_send_conn_req(chan);
1137 }
1138}
1139
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001140static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001141{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001142 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001143
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001144 if (conn->hcon->type == LE_LINK) {
1145 l2cap_chan_ready(chan);
1146 return;
1147 }
1148
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001149 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001150 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1151 return;
1152
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001153 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001154 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001155 l2cap_start_connection(chan);
1156 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001157 } else {
1158 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001159 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001160
1161 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1162 conn->info_ident = l2cap_get_ident(conn);
1163
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001164 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001165
Gustavo Padovan2d792812012-10-06 10:07:01 +01001166 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1167 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001168 }
1169}
1170
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001171static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1172{
1173 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001174 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001175 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1176
1177 switch (mode) {
1178 case L2CAP_MODE_ERTM:
1179 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1180 case L2CAP_MODE_STREAMING:
1181 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1182 default:
1183 return 0x00;
1184 }
1185}
1186
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001187static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001188{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001189 struct sock *sk = chan->sk;
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001190 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001191 struct l2cap_disconn_req req;
1192
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001193 if (!conn)
1194 return;
1195
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001196 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001197 __clear_retrans_timer(chan);
1198 __clear_monitor_timer(chan);
1199 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001200 }
1201
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001202 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001203 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001204 return;
1205 }
1206
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001207 req.dcid = cpu_to_le16(chan->dcid);
1208 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001209 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1210 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001211
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001212 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001213 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001214 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001215 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001216}
1217
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001219static void l2cap_conn_start(struct l2cap_conn *conn)
1220{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001221 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001222
1223 BT_DBG("conn %p", conn);
1224
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001225 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001226
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001227 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001228 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001229
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001230 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001231
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001232 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001233 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001234 continue;
1235 }
1236
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001237 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001238 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001239 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001240 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001241 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001242 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001243
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001244 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001245 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001246 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001247 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001248 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001249 continue;
1250 }
1251
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001252 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001253
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001254 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001255 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001256 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001257 rsp.scid = cpu_to_le16(chan->dcid);
1258 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001259
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001260 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001261 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001262 if (test_bit(BT_SK_DEFER_SETUP,
1263 &bt_sk(sk)->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001264 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1265 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001266 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001267
1268 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001269 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001270 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1271 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001272 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001273 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001274 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001275 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1276 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001277 }
1278
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001279 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001280 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001281
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001282 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001283 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001284 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001285 continue;
1286 }
1287
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001288 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001289 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001290 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001291 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001292 }
1293
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001294 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001295 }
1296
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001297 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001298}
1299
Ido Yarivc2287682012-04-20 15:46:07 -03001300/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001301 * Returns closest match, locked.
1302 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001303static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001304 bdaddr_t *src,
1305 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001306{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001307 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001308
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001309 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001310
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001311 list_for_each_entry(c, &chan_list, global_l) {
1312 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001313
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001314 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001315 continue;
1316
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001317 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001318 int src_match, dst_match;
1319 int src_any, dst_any;
1320
Ville Tervob62f3282011-02-10 22:38:50 -03001321 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001322 src_match = !bacmp(&bt_sk(sk)->src, src);
1323 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1324 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001325 read_unlock(&chan_list_lock);
1326 return c;
1327 }
Ville Tervob62f3282011-02-10 22:38:50 -03001328
1329 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001330 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1331 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1332 if ((src_match && dst_any) || (src_any && dst_match) ||
1333 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001334 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001335 }
1336 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001337
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001338 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001339
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001340 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001341}
1342
1343static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1344{
Johan Hedberg60bac182013-04-29 19:35:41 +03001345 struct sock *parent;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001346 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001347
1348 BT_DBG("");
1349
1350 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001351 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Ido Yarivc2287682012-04-20 15:46:07 -03001352 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001353 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001354 return;
1355
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001356 /* Client ATT sockets should override the server one */
1357 if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
1358 return;
1359
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001360 parent = pchan->sk;
1361
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001362 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001363
Gustavo Padovan80b98022012-05-27 22:27:51 -03001364 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001365 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001366 goto clean;
1367
Johan Hedberg9f22398c2013-04-29 19:35:38 +03001368 chan->dcid = L2CAP_CID_ATT;
1369
Johan Hedberg60bac182013-04-29 19:35:41 +03001370 bacpy(&bt_sk(chan->sk)->src, conn->src);
1371 bacpy(&bt_sk(chan->sk)->dst, conn->dst);
Ville Tervob62f3282011-02-10 22:38:50 -03001372
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001373 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001374
Ville Tervob62f3282011-02-10 22:38:50 -03001375clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001376 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001377}
1378
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001379static void l2cap_conn_ready(struct l2cap_conn *conn)
1380{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001381 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001382 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001383
1384 BT_DBG("conn %p", conn);
1385
Johan Hedbergd8729922013-04-29 19:35:39 +03001386 /* For outgoing pairing which doesn't necessarily have an
1387 * associated socket (e.g. mgmt_pair_device).
1388 */
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001389 if (hcon->out && hcon->type == LE_LINK)
1390 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001391
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001392 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001393
Johan Hedberg44f3b0f2013-04-29 19:35:45 +03001394 if (hcon->type == LE_LINK)
1395 l2cap_le_conn_ready(conn);
1396
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001397 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001398
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001399 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001400
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001401 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1402 l2cap_chan_unlock(chan);
1403 continue;
1404 }
1405
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001406 if (hcon->type == LE_LINK) {
1407 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001408 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001409
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001410 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001411 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001412 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001413 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001414 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001415 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001416 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001417
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001418 } else if (chan->state == BT_CONNECT) {
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001419 l2cap_do_start(chan);
Gustavo Padovan1c244f72012-12-07 03:29:10 -02001420 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001421
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001422 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001423 }
1424
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001425 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001426}
1427
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001428/* Notify sockets that we cannot guaranty reliability anymore */
1429static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1430{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001431 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001432
1433 BT_DBG("conn %p", conn);
1434
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001435 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001436
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001437 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001438 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001439 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001440 }
1441
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001442 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001443}
1444
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001445static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001446{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001447 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001448 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001449
Marcel Holtmann984947d2009-02-06 23:35:19 +01001450 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001451 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001452
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001453 l2cap_conn_start(conn);
1454}
1455
David Herrmann2c8e1412013-04-06 20:28:45 +02001456/*
1457 * l2cap_user
1458 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1459 * callback is called during registration. The ->remove callback is called
1460 * during unregistration.
1461 * An l2cap_user object can either be explicitly unregistered or when the
1462 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1463 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1464 * External modules must own a reference to the l2cap_conn object if they intend
1465 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1466 * any time if they don't.
1467 */
1468
1469int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1470{
1471 struct hci_dev *hdev = conn->hcon->hdev;
1472 int ret;
1473
1474 /* We need to check whether l2cap_conn is registered. If it is not, we
1475 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1476 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1477 * relies on the parent hci_conn object to be locked. This itself relies
1478 * on the hci_dev object to be locked. So we must lock the hci device
1479 * here, too. */
1480
1481 hci_dev_lock(hdev);
1482
1483 if (user->list.next || user->list.prev) {
1484 ret = -EINVAL;
1485 goto out_unlock;
1486 }
1487
1488 /* conn->hchan is NULL after l2cap_conn_del() was called */
1489 if (!conn->hchan) {
1490 ret = -ENODEV;
1491 goto out_unlock;
1492 }
1493
1494 ret = user->probe(conn, user);
1495 if (ret)
1496 goto out_unlock;
1497
1498 list_add(&user->list, &conn->users);
1499 ret = 0;
1500
1501out_unlock:
1502 hci_dev_unlock(hdev);
1503 return ret;
1504}
1505EXPORT_SYMBOL(l2cap_register_user);
1506
1507void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1508{
1509 struct hci_dev *hdev = conn->hcon->hdev;
1510
1511 hci_dev_lock(hdev);
1512
1513 if (!user->list.next || !user->list.prev)
1514 goto out_unlock;
1515
1516 list_del(&user->list);
1517 user->list.next = NULL;
1518 user->list.prev = NULL;
1519 user->remove(conn, user);
1520
1521out_unlock:
1522 hci_dev_unlock(hdev);
1523}
1524EXPORT_SYMBOL(l2cap_unregister_user);
1525
1526static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1527{
1528 struct l2cap_user *user;
1529
1530 while (!list_empty(&conn->users)) {
1531 user = list_first_entry(&conn->users, struct l2cap_user, list);
1532 list_del(&user->list);
1533 user->list.next = NULL;
1534 user->list.prev = NULL;
1535 user->remove(conn, user);
1536 }
1537}
1538
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001539static void l2cap_conn_del(struct hci_conn *hcon, int err)
1540{
1541 struct l2cap_conn *conn = hcon->l2cap_data;
1542 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001543
1544 if (!conn)
1545 return;
1546
1547 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1548
1549 kfree_skb(conn->rx_skb);
1550
David Herrmann2c8e1412013-04-06 20:28:45 +02001551 l2cap_unregister_all_users(conn);
1552
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001553 mutex_lock(&conn->chan_lock);
1554
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001555 /* Kill channels */
1556 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001557 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001558 l2cap_chan_lock(chan);
1559
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001560 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001561
1562 l2cap_chan_unlock(chan);
1563
Gustavo Padovan80b98022012-05-27 22:27:51 -03001564 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001565 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001566 }
1567
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001568 mutex_unlock(&conn->chan_lock);
1569
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001570 hci_chan_del(conn->hchan);
1571
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001572 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001573 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001574
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001575 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001576 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001577 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001578 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001579
1580 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001581 conn->hchan = NULL;
1582 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001583}
1584
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001585static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001586{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001587 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001588 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001589
Johan Hedbergd06cc412012-06-06 18:44:11 +08001590 BT_DBG("conn %p", conn);
1591
1592 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1593 smp_chan_destroy(conn);
1594 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1595 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001596}
1597
Claudio Takahasibaf43252013-04-11 13:55:50 -03001598static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599{
Marcel Holtmann01394182006-07-03 10:02:46 +02001600 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001601 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602
Claudio Takahasibaf43252013-04-11 13:55:50 -03001603 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604 return conn;
1605
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001606 hchan = hci_chan_create(hcon);
1607 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001610 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001611 if (!conn) {
1612 hci_chan_del(hchan);
1613 return NULL;
1614 }
1615
David Herrmann9c903e32013-04-06 20:28:44 +02001616 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617 hcon->l2cap_data = conn;
1618 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001619 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001620 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001622 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001623
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001624 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001625 case LE_LINK:
1626 if (hcon->hdev->le_mtu) {
1627 conn->mtu = hcon->hdev->le_mtu;
1628 break;
1629 }
1630 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001631 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001632 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001633 break;
1634 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001635
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636 conn->src = &hcon->hdev->bdaddr;
1637 conn->dst = &hcon->dst;
1638
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001639 conn->feat_mask = 0;
1640
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001642 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001643
1644 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001645 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001646
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001647 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001648 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001649 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001650 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001651
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001652 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001653
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654 return conn;
1655}
1656
David Herrmann9c903e32013-04-06 20:28:44 +02001657static void l2cap_conn_free(struct kref *ref)
1658{
1659 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1660
1661 hci_conn_put(conn->hcon);
1662 kfree(conn);
1663}
1664
1665void l2cap_conn_get(struct l2cap_conn *conn)
1666{
1667 kref_get(&conn->ref);
1668}
1669EXPORT_SYMBOL(l2cap_conn_get);
1670
1671void l2cap_conn_put(struct l2cap_conn *conn)
1672{
1673 kref_put(&conn->ref, l2cap_conn_free);
1674}
1675EXPORT_SYMBOL(l2cap_conn_put);
1676
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678
Ido Yarivc2287682012-04-20 15:46:07 -03001679/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680 * Returns closest match.
1681 */
Ido Yarivc2287682012-04-20 15:46:07 -03001682static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1683 bdaddr_t *src,
1684 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001686 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001688 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001689
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001690 list_for_each_entry(c, &chan_list, global_l) {
1691 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001692
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001693 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694 continue;
1695
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001696 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001697 int src_match, dst_match;
1698 int src_any, dst_any;
1699
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001701 src_match = !bacmp(&bt_sk(sk)->src, src);
1702 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1703 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001704 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001705 return c;
1706 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707
1708 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001709 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1710 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1711 if ((src_match && dst_any) || (src_any && dst_match) ||
1712 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001713 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714 }
1715 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001717 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001718
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001719 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720}
1721
Andre Guedes8e9f9892012-04-24 21:02:55 -03001722int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1723 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001725 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 struct l2cap_conn *conn;
1728 struct hci_conn *hcon;
1729 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001730 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001731 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001733 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301734 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001736 hdev = hci_get_route(dst, src);
1737 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 return -EHOSTUNREACH;
1739
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001740 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001742 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001743
1744 /* PSM must be odd and lsb of upper byte must be 0 */
1745 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001746 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001747 err = -EINVAL;
1748 goto done;
1749 }
1750
1751 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1752 err = -EINVAL;
1753 goto done;
1754 }
1755
1756 switch (chan->mode) {
1757 case L2CAP_MODE_BASIC:
1758 break;
1759 case L2CAP_MODE_ERTM:
1760 case L2CAP_MODE_STREAMING:
1761 if (!disable_ertm)
1762 break;
1763 /* fall through */
1764 default:
1765 err = -ENOTSUPP;
1766 goto done;
1767 }
1768
Gustavo Padovan0797e012012-05-27 22:27:54 -03001769 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001770 case BT_CONNECT:
1771 case BT_CONNECT2:
1772 case BT_CONFIG:
1773 /* Already connecting */
1774 err = 0;
1775 goto done;
1776
1777 case BT_CONNECTED:
1778 /* Already connected */
1779 err = -EISCONN;
1780 goto done;
1781
1782 case BT_OPEN:
1783 case BT_BOUND:
1784 /* Can connect */
1785 break;
1786
1787 default:
1788 err = -EBADFD;
1789 goto done;
1790 }
1791
1792 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001793 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001794 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001795 release_sock(sk);
1796
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001797 chan->psm = psm;
1798 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001800 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001801
Johan Hedbergf224ca52013-04-29 19:35:36 +03001802 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001803 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001804 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001805 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001806 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001807 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001808
Ville Tervo30e76272011-02-22 16:10:53 -03001809 if (IS_ERR(hcon)) {
1810 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001812 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813
Claudio Takahasibaf43252013-04-11 13:55:50 -03001814 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001816 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001817 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818 goto done;
1819 }
1820
Johan Hedberg141d5702013-04-29 19:35:37 +03001821 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1822 hci_conn_drop(hcon);
1823 err = -EBUSY;
1824 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001825 }
1826
Linus Torvalds1da177e2005-04-16 15:20:36 -07001827 /* Update source addr of the socket */
1828 bacpy(src, conn->src);
1829
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001830 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001831 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001832 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001833
Johan Hedberg5ee98912013-04-29 19:35:43 +03001834 /* l2cap_chan_add takes its own ref so we can drop this one */
1835 hci_conn_drop(hcon);
1836
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001837 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001838 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839
1840 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001841 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001842 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001843 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001844 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001845 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001846 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847 }
1848
Ville Tervo30e76272011-02-22 16:10:53 -03001849 err = 0;
1850
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001852 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001853 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854 hci_dev_put(hdev);
1855 return err;
1856}
1857
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001858int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001859{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001860 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001861 DECLARE_WAITQUEUE(wait, current);
1862 int err = 0;
1863 int timeo = HZ/5;
1864
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001865 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001866 set_current_state(TASK_INTERRUPTIBLE);
1867 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001868 if (!timeo)
1869 timeo = HZ/5;
1870
1871 if (signal_pending(current)) {
1872 err = sock_intr_errno(timeo);
1873 break;
1874 }
1875
1876 release_sock(sk);
1877 timeo = schedule_timeout(timeo);
1878 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001879 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001880
1881 err = sock_error(sk);
1882 if (err)
1883 break;
1884 }
1885 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001886 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001887 return err;
1888}
1889
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001890static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001891{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001892 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001893 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001894
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001895 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001896
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001897 l2cap_chan_lock(chan);
1898
Mat Martineau80909e02012-05-17 20:53:50 -07001899 if (!chan->conn) {
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 return;
1903 }
1904
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001905 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001906
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001907 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001908 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001909}
1910
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001911static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001912{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001913 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001914 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001915
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001916 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001917
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001918 l2cap_chan_lock(chan);
1919
Mat Martineau80909e02012-05-17 20:53:50 -07001920 if (!chan->conn) {
1921 l2cap_chan_unlock(chan);
1922 l2cap_chan_put(chan);
1923 return;
1924 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001925
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001926 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001927 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001928 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001929}
1930
Gustavo Padovand6603662012-05-21 13:58:22 -03001931static void l2cap_streaming_send(struct l2cap_chan *chan,
1932 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001933{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001934 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001935 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001936
Mat Martineau37339372012-05-17 20:53:33 -07001937 BT_DBG("chan %p, skbs %p", chan, skbs);
1938
Mat Martineaub99e13a2012-10-23 15:24:19 -07001939 if (__chan_is_moving(chan))
1940 return;
1941
Mat Martineau37339372012-05-17 20:53:33 -07001942 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1943
1944 while (!skb_queue_empty(&chan->tx_q)) {
1945
1946 skb = skb_dequeue(&chan->tx_q);
1947
1948 bt_cb(skb)->control.retries = 1;
1949 control = &bt_cb(skb)->control;
1950
1951 control->reqseq = 0;
1952 control->txseq = chan->next_tx_seq;
1953
1954 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001955
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001956 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001957 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1958 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001959 }
1960
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001961 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001962
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001963 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001964
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001965 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001966 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001967 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001968}
1969
Szymon Janc67c9e842011-07-28 16:24:33 +02001970static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001971{
1972 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001973 struct l2cap_ctrl *control;
1974 int sent = 0;
1975
1976 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001977
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001978 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001979 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001980
Mat Martineau94122bb2012-05-02 09:42:02 -07001981 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1982 return 0;
1983
Mat Martineaub99e13a2012-10-23 15:24:19 -07001984 if (__chan_is_moving(chan))
1985 return 0;
1986
Mat Martineau18a48e72012-05-17 20:53:34 -07001987 while (chan->tx_send_head &&
1988 chan->unacked_frames < chan->remote_tx_win &&
1989 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001990
Mat Martineau18a48e72012-05-17 20:53:34 -07001991 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001992
Mat Martineau18a48e72012-05-17 20:53:34 -07001993 bt_cb(skb)->control.retries = 1;
1994 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001995
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001996 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001997 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001998
Mat Martineau18a48e72012-05-17 20:53:34 -07001999 control->reqseq = chan->buffer_seq;
2000 chan->last_acked_seq = chan->buffer_seq;
2001 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002002
Mat Martineau18a48e72012-05-17 20:53:34 -07002003 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002004
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002005 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07002006 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
2007 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002008 }
2009
Mat Martineau18a48e72012-05-17 20:53:34 -07002010 /* Clone after data has been modified. Data is assumed to be
2011 read-only (for locking purposes) on cloned sk_buffs.
2012 */
2013 tx_skb = skb_clone(skb, GFP_KERNEL);
2014
2015 if (!tx_skb)
2016 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002017
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002018 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002019
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002020 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002021 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002022 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002023 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002024
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002025 if (skb_queue_is_last(&chan->tx_q, skb))
2026 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002027 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002028 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002029
2030 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002031 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002032 }
2033
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002034 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2035 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002036
2037 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002038}
2039
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002040static void l2cap_ertm_resend(struct l2cap_chan *chan)
2041{
2042 struct l2cap_ctrl control;
2043 struct sk_buff *skb;
2044 struct sk_buff *tx_skb;
2045 u16 seq;
2046
2047 BT_DBG("chan %p", chan);
2048
2049 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2050 return;
2051
Mat Martineaub99e13a2012-10-23 15:24:19 -07002052 if (__chan_is_moving(chan))
2053 return;
2054
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002055 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2056 seq = l2cap_seq_list_pop(&chan->retrans_list);
2057
2058 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2059 if (!skb) {
2060 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002061 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002062 continue;
2063 }
2064
2065 bt_cb(skb)->control.retries++;
2066 control = bt_cb(skb)->control;
2067
2068 if (chan->max_tx != 0 &&
2069 bt_cb(skb)->control.retries > chan->max_tx) {
2070 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002071 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002072 l2cap_seq_list_clear(&chan->retrans_list);
2073 break;
2074 }
2075
2076 control.reqseq = chan->buffer_seq;
2077 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2078 control.final = 1;
2079 else
2080 control.final = 0;
2081
2082 if (skb_cloned(skb)) {
2083 /* Cloned sk_buffs are read-only, so we need a
2084 * writeable copy
2085 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002086 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002087 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002088 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002089 }
2090
2091 if (!tx_skb) {
2092 l2cap_seq_list_clear(&chan->retrans_list);
2093 break;
2094 }
2095
2096 /* Update skb contents */
2097 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2098 put_unaligned_le32(__pack_extended_control(&control),
2099 tx_skb->data + L2CAP_HDR_SIZE);
2100 } else {
2101 put_unaligned_le16(__pack_enhanced_control(&control),
2102 tx_skb->data + L2CAP_HDR_SIZE);
2103 }
2104
2105 if (chan->fcs == L2CAP_FCS_CRC16) {
2106 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2107 put_unaligned_le16(fcs, skb_put(tx_skb,
2108 L2CAP_FCS_SIZE));
2109 }
2110
2111 l2cap_do_send(chan, tx_skb);
2112
2113 BT_DBG("Resent txseq %d", control.txseq);
2114
2115 chan->last_acked_seq = chan->buffer_seq;
2116 }
2117}
2118
Mat Martineauf80842a2012-05-17 20:53:46 -07002119static void l2cap_retransmit(struct l2cap_chan *chan,
2120 struct l2cap_ctrl *control)
2121{
2122 BT_DBG("chan %p, control %p", chan, control);
2123
2124 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2125 l2cap_ertm_resend(chan);
2126}
2127
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002128static void l2cap_retransmit_all(struct l2cap_chan *chan,
2129 struct l2cap_ctrl *control)
2130{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002131 struct sk_buff *skb;
2132
2133 BT_DBG("chan %p, control %p", chan, control);
2134
2135 if (control->poll)
2136 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2137
2138 l2cap_seq_list_clear(&chan->retrans_list);
2139
2140 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2141 return;
2142
2143 if (chan->unacked_frames) {
2144 skb_queue_walk(&chan->tx_q, skb) {
2145 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002146 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002147 break;
2148 }
2149
2150 skb_queue_walk_from(&chan->tx_q, skb) {
2151 if (skb == chan->tx_send_head)
2152 break;
2153
2154 l2cap_seq_list_append(&chan->retrans_list,
2155 bt_cb(skb)->control.txseq);
2156 }
2157
2158 l2cap_ertm_resend(chan);
2159 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002160}
2161
Szymon Jancb17e73b2012-01-11 10:59:47 +01002162static void l2cap_send_ack(struct l2cap_chan *chan)
2163{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002164 struct l2cap_ctrl control;
2165 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2166 chan->last_acked_seq);
2167 int threshold;
2168
2169 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2170 chan, chan->last_acked_seq, chan->buffer_seq);
2171
2172 memset(&control, 0, sizeof(control));
2173 control.sframe = 1;
2174
2175 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2176 chan->rx_state == L2CAP_RX_STATE_RECV) {
2177 __clear_ack_timer(chan);
2178 control.super = L2CAP_SUPER_RNR;
2179 control.reqseq = chan->buffer_seq;
2180 l2cap_send_sframe(chan, &control);
2181 } else {
2182 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2183 l2cap_ertm_send(chan);
2184 /* If any i-frames were sent, they included an ack */
2185 if (chan->buffer_seq == chan->last_acked_seq)
2186 frames_to_ack = 0;
2187 }
2188
Mat Martineauc20f8e32012-07-10 05:47:07 -07002189 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002190 * Calculate without mul or div
2191 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002192 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002193 threshold += threshold << 1;
2194 threshold >>= 2;
2195
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002196 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002197 threshold);
2198
2199 if (frames_to_ack >= threshold) {
2200 __clear_ack_timer(chan);
2201 control.super = L2CAP_SUPER_RR;
2202 control.reqseq = chan->buffer_seq;
2203 l2cap_send_sframe(chan, &control);
2204 frames_to_ack = 0;
2205 }
2206
2207 if (frames_to_ack)
2208 __set_ack_timer(chan);
2209 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002210}
2211
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002212static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2213 struct msghdr *msg, int len,
2214 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002215{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002216 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002217 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002218 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002219
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002220 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002221 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002222
2223 sent += count;
2224 len -= count;
2225
2226 /* Continuation fragments (no L2CAP header) */
2227 frag = &skb_shinfo(skb)->frag_list;
2228 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002229 struct sk_buff *tmp;
2230
Linus Torvalds1da177e2005-04-16 15:20:36 -07002231 count = min_t(unsigned int, conn->mtu, len);
2232
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002233 tmp = chan->ops->alloc_skb(chan, count,
2234 msg->msg_flags & MSG_DONTWAIT);
2235 if (IS_ERR(tmp))
2236 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002237
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002238 *frag = tmp;
2239
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002240 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2241 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002242
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002243 (*frag)->priority = skb->priority;
2244
Linus Torvalds1da177e2005-04-16 15:20:36 -07002245 sent += count;
2246 len -= count;
2247
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002248 skb->len += (*frag)->len;
2249 skb->data_len += (*frag)->len;
2250
Linus Torvalds1da177e2005-04-16 15:20:36 -07002251 frag = &(*frag)->next;
2252 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002253
2254 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002255}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002256
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002257static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002258 struct msghdr *msg, size_t len,
2259 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002260{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002261 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002262 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002263 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002264 struct l2cap_hdr *lh;
2265
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002266 BT_DBG("chan %p len %zu priority %u", chan, len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002267
2268 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002269
2270 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002271 msg->msg_flags & MSG_DONTWAIT);
2272 if (IS_ERR(skb))
2273 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002274
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002275 skb->priority = priority;
2276
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002277 /* Create L2CAP header */
2278 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002279 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002280 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
2281 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002282
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002283 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002284 if (unlikely(err < 0)) {
2285 kfree_skb(skb);
2286 return ERR_PTR(err);
2287 }
2288 return skb;
2289}
2290
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002291static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002292 struct msghdr *msg, size_t len,
2293 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002294{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002295 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002296 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002297 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002298 struct l2cap_hdr *lh;
2299
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002300 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002301
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002302 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002303
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002304 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002305 msg->msg_flags & MSG_DONTWAIT);
2306 if (IS_ERR(skb))
2307 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002308
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002309 skb->priority = priority;
2310
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002311 /* Create L2CAP header */
2312 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002313 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002314 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002315
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002316 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002317 if (unlikely(err < 0)) {
2318 kfree_skb(skb);
2319 return ERR_PTR(err);
2320 }
2321 return skb;
2322}
2323
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002324static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002325 struct msghdr *msg, size_t len,
2326 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002327{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002328 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002329 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002330 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002331 struct l2cap_hdr *lh;
2332
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002333 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002334
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002335 if (!conn)
2336 return ERR_PTR(-ENOTCONN);
2337
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002338 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002339
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002340 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002341 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002342
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002343 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002344 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002345
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002346 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002347
2348 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002349 msg->msg_flags & MSG_DONTWAIT);
2350 if (IS_ERR(skb))
2351 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002352
2353 /* Create L2CAP header */
2354 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002355 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002356 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002357
Mat Martineau18a48e72012-05-17 20:53:34 -07002358 /* Control header is populated later */
2359 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2360 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2361 else
2362 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002363
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002364 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002365 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002366
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002367 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002368 if (unlikely(err < 0)) {
2369 kfree_skb(skb);
2370 return ERR_PTR(err);
2371 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002372
Mat Martineau18a48e72012-05-17 20:53:34 -07002373 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002374 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002375 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002376}
2377
Mat Martineau94122bb2012-05-02 09:42:02 -07002378static int l2cap_segment_sdu(struct l2cap_chan *chan,
2379 struct sk_buff_head *seg_queue,
2380 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002381{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002382 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002383 u16 sdu_len;
2384 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002385 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002386
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002387 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002388
Mat Martineau94122bb2012-05-02 09:42:02 -07002389 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2390 * so fragmented skbs are not used. The HCI layer's handling
2391 * of fragmented skbs is not compatible with ERTM's queueing.
2392 */
2393
2394 /* PDU size is derived from the HCI MTU */
2395 pdu_len = chan->conn->mtu;
2396
Mat Martineaua5495742012-10-23 15:24:21 -07002397 /* Constrain PDU size for BR/EDR connections */
2398 if (!chan->hs_hcon)
2399 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002400
2401 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002402 if (chan->fcs)
2403 pdu_len -= L2CAP_FCS_SIZE;
2404
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002405 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002406
2407 /* Remote device may have requested smaller PDUs */
2408 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2409
2410 if (len <= pdu_len) {
2411 sar = L2CAP_SAR_UNSEGMENTED;
2412 sdu_len = 0;
2413 pdu_len = len;
2414 } else {
2415 sar = L2CAP_SAR_START;
2416 sdu_len = len;
2417 pdu_len -= L2CAP_SDULEN_SIZE;
2418 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002419
2420 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002421 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002422
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002423 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002424 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002425 return PTR_ERR(skb);
2426 }
2427
Mat Martineau94122bb2012-05-02 09:42:02 -07002428 bt_cb(skb)->control.sar = sar;
2429 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002430
Mat Martineau94122bb2012-05-02 09:42:02 -07002431 len -= pdu_len;
2432 if (sdu_len) {
2433 sdu_len = 0;
2434 pdu_len += L2CAP_SDULEN_SIZE;
2435 }
2436
2437 if (len <= pdu_len) {
2438 sar = L2CAP_SAR_END;
2439 pdu_len = len;
2440 } else {
2441 sar = L2CAP_SAR_CONTINUE;
2442 }
2443 }
2444
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002445 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002446}
2447
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002448int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002449 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002450{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002451 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002452 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002453 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002454
2455 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002456 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002457 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002458 if (IS_ERR(skb))
2459 return PTR_ERR(skb);
2460
2461 l2cap_do_send(chan, skb);
2462 return len;
2463 }
2464
2465 switch (chan->mode) {
2466 case L2CAP_MODE_BASIC:
2467 /* Check outgoing MTU */
2468 if (len > chan->omtu)
2469 return -EMSGSIZE;
2470
2471 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002472 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002473 if (IS_ERR(skb))
2474 return PTR_ERR(skb);
2475
2476 l2cap_do_send(chan, skb);
2477 err = len;
2478 break;
2479
2480 case L2CAP_MODE_ERTM:
2481 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002482 /* Check outgoing MTU */
2483 if (len > chan->omtu) {
2484 err = -EMSGSIZE;
2485 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002486 }
2487
Mat Martineau94122bb2012-05-02 09:42:02 -07002488 __skb_queue_head_init(&seg_queue);
2489
2490 /* Do segmentation before calling in to the state machine,
2491 * since it's possible to block while waiting for memory
2492 * allocation.
2493 */
2494 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2495
2496 /* The channel could have been closed while segmenting,
2497 * check that it is still connected.
2498 */
2499 if (chan->state != BT_CONNECTED) {
2500 __skb_queue_purge(&seg_queue);
2501 err = -ENOTCONN;
2502 }
2503
2504 if (err)
2505 break;
2506
Mat Martineau37339372012-05-17 20:53:33 -07002507 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002508 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002509 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002510 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002511
Gustavo Padovand6603662012-05-21 13:58:22 -03002512 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002513
Mat Martineau94122bb2012-05-02 09:42:02 -07002514 /* If the skbs were not queued for sending, they'll still be in
2515 * seg_queue and need to be purged.
2516 */
2517 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002518 break;
2519
2520 default:
2521 BT_DBG("bad state %1.1x", chan->mode);
2522 err = -EBADFD;
2523 }
2524
2525 return err;
2526}
2527
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002528static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2529{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002530 struct l2cap_ctrl control;
2531 u16 seq;
2532
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002533 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002534
2535 memset(&control, 0, sizeof(control));
2536 control.sframe = 1;
2537 control.super = L2CAP_SUPER_SREJ;
2538
2539 for (seq = chan->expected_tx_seq; seq != txseq;
2540 seq = __next_seq(chan, seq)) {
2541 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2542 control.reqseq = seq;
2543 l2cap_send_sframe(chan, &control);
2544 l2cap_seq_list_append(&chan->srej_list, seq);
2545 }
2546 }
2547
2548 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002549}
2550
2551static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2552{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002553 struct l2cap_ctrl control;
2554
2555 BT_DBG("chan %p", chan);
2556
2557 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2558 return;
2559
2560 memset(&control, 0, sizeof(control));
2561 control.sframe = 1;
2562 control.super = L2CAP_SUPER_SREJ;
2563 control.reqseq = chan->srej_list.tail;
2564 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002565}
2566
2567static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2568{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002569 struct l2cap_ctrl control;
2570 u16 initial_head;
2571 u16 seq;
2572
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002573 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002574
2575 memset(&control, 0, sizeof(control));
2576 control.sframe = 1;
2577 control.super = L2CAP_SUPER_SREJ;
2578
2579 /* Capture initial list head to allow only one pass through the list. */
2580 initial_head = chan->srej_list.head;
2581
2582 do {
2583 seq = l2cap_seq_list_pop(&chan->srej_list);
2584 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2585 break;
2586
2587 control.reqseq = seq;
2588 l2cap_send_sframe(chan, &control);
2589 l2cap_seq_list_append(&chan->srej_list, seq);
2590 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002591}
2592
Mat Martineau608bcc62012-05-17 20:53:32 -07002593static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2594{
2595 struct sk_buff *acked_skb;
2596 u16 ackseq;
2597
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002598 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002599
2600 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2601 return;
2602
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002603 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002604 chan->expected_ack_seq, chan->unacked_frames);
2605
2606 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2607 ackseq = __next_seq(chan, ackseq)) {
2608
2609 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2610 if (acked_skb) {
2611 skb_unlink(acked_skb, &chan->tx_q);
2612 kfree_skb(acked_skb);
2613 chan->unacked_frames--;
2614 }
2615 }
2616
2617 chan->expected_ack_seq = reqseq;
2618
2619 if (chan->unacked_frames == 0)
2620 __clear_retrans_timer(chan);
2621
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002622 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002623}
2624
2625static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2626{
2627 BT_DBG("chan %p", chan);
2628
2629 chan->expected_tx_seq = chan->buffer_seq;
2630 l2cap_seq_list_clear(&chan->srej_list);
2631 skb_queue_purge(&chan->srej_q);
2632 chan->rx_state = L2CAP_RX_STATE_RECV;
2633}
2634
Gustavo Padovand6603662012-05-21 13:58:22 -03002635static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2636 struct l2cap_ctrl *control,
2637 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002638{
Mat Martineau608bcc62012-05-17 20:53:32 -07002639 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2640 event);
2641
2642 switch (event) {
2643 case L2CAP_EV_DATA_REQUEST:
2644 if (chan->tx_send_head == NULL)
2645 chan->tx_send_head = skb_peek(skbs);
2646
2647 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2648 l2cap_ertm_send(chan);
2649 break;
2650 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2651 BT_DBG("Enter LOCAL_BUSY");
2652 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2653
2654 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2655 /* The SREJ_SENT state must be aborted if we are to
2656 * enter the LOCAL_BUSY state.
2657 */
2658 l2cap_abort_rx_srej_sent(chan);
2659 }
2660
2661 l2cap_send_ack(chan);
2662
2663 break;
2664 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2665 BT_DBG("Exit LOCAL_BUSY");
2666 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2667
2668 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2669 struct l2cap_ctrl local_control;
2670
2671 memset(&local_control, 0, sizeof(local_control));
2672 local_control.sframe = 1;
2673 local_control.super = L2CAP_SUPER_RR;
2674 local_control.poll = 1;
2675 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002676 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002677
2678 chan->retry_count = 1;
2679 __set_monitor_timer(chan);
2680 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2681 }
2682 break;
2683 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2684 l2cap_process_reqseq(chan, control->reqseq);
2685 break;
2686 case L2CAP_EV_EXPLICIT_POLL:
2687 l2cap_send_rr_or_rnr(chan, 1);
2688 chan->retry_count = 1;
2689 __set_monitor_timer(chan);
2690 __clear_ack_timer(chan);
2691 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2692 break;
2693 case L2CAP_EV_RETRANS_TO:
2694 l2cap_send_rr_or_rnr(chan, 1);
2695 chan->retry_count = 1;
2696 __set_monitor_timer(chan);
2697 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2698 break;
2699 case L2CAP_EV_RECV_FBIT:
2700 /* Nothing to process */
2701 break;
2702 default:
2703 break;
2704 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002705}
2706
Gustavo Padovand6603662012-05-21 13:58:22 -03002707static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2708 struct l2cap_ctrl *control,
2709 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002710{
Mat Martineau608bcc62012-05-17 20:53:32 -07002711 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2712 event);
2713
2714 switch (event) {
2715 case L2CAP_EV_DATA_REQUEST:
2716 if (chan->tx_send_head == NULL)
2717 chan->tx_send_head = skb_peek(skbs);
2718 /* Queue data, but don't send. */
2719 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2720 break;
2721 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2722 BT_DBG("Enter LOCAL_BUSY");
2723 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2724
2725 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2726 /* The SREJ_SENT state must be aborted if we are to
2727 * enter the LOCAL_BUSY state.
2728 */
2729 l2cap_abort_rx_srej_sent(chan);
2730 }
2731
2732 l2cap_send_ack(chan);
2733
2734 break;
2735 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2736 BT_DBG("Exit LOCAL_BUSY");
2737 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2738
2739 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2740 struct l2cap_ctrl local_control;
2741 memset(&local_control, 0, sizeof(local_control));
2742 local_control.sframe = 1;
2743 local_control.super = L2CAP_SUPER_RR;
2744 local_control.poll = 1;
2745 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002746 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002747
2748 chan->retry_count = 1;
2749 __set_monitor_timer(chan);
2750 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2751 }
2752 break;
2753 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2754 l2cap_process_reqseq(chan, control->reqseq);
2755
2756 /* Fall through */
2757
2758 case L2CAP_EV_RECV_FBIT:
2759 if (control && control->final) {
2760 __clear_monitor_timer(chan);
2761 if (chan->unacked_frames > 0)
2762 __set_retrans_timer(chan);
2763 chan->retry_count = 0;
2764 chan->tx_state = L2CAP_TX_STATE_XMIT;
2765 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2766 }
2767 break;
2768 case L2CAP_EV_EXPLICIT_POLL:
2769 /* Ignore */
2770 break;
2771 case L2CAP_EV_MONITOR_TO:
2772 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2773 l2cap_send_rr_or_rnr(chan, 1);
2774 __set_monitor_timer(chan);
2775 chan->retry_count++;
2776 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002777 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002778 }
2779 break;
2780 default:
2781 break;
2782 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002783}
2784
Gustavo Padovand6603662012-05-21 13:58:22 -03002785static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2786 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002787{
Mat Martineau608bcc62012-05-17 20:53:32 -07002788 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2789 chan, control, skbs, event, chan->tx_state);
2790
2791 switch (chan->tx_state) {
2792 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002793 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002794 break;
2795 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002796 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002797 break;
2798 default:
2799 /* Ignore event */
2800 break;
2801 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002802}
2803
Mat Martineau4b51dae92012-05-17 20:53:37 -07002804static void l2cap_pass_to_tx(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_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002809}
2810
Mat Martineauf80842a2012-05-17 20:53:46 -07002811static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2812 struct l2cap_ctrl *control)
2813{
2814 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002815 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002816}
2817
Linus Torvalds1da177e2005-04-16 15:20:36 -07002818/* Copy frame to all raw sockets on that connection */
2819static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2820{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002821 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002822 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002823
2824 BT_DBG("conn %p", conn);
2825
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002826 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002827
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002828 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002829 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002830 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002831 continue;
2832
2833 /* Don't send frame to the socket it came from */
2834 if (skb->sk == sk)
2835 continue;
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002836 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002837 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002838 continue;
2839
Gustavo Padovan80b98022012-05-27 22:27:51 -03002840 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002841 kfree_skb(nskb);
2842 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002843
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002844 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002845}
2846
2847/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002848static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2849 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002850{
2851 struct sk_buff *skb, **frag;
2852 struct l2cap_cmd_hdr *cmd;
2853 struct l2cap_hdr *lh;
2854 int len, count;
2855
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002856 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2857 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002858
Anderson Lizardo300b9622013-06-02 16:30:40 -04002859 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2860 return NULL;
2861
Linus Torvalds1da177e2005-04-16 15:20:36 -07002862 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2863 count = min_t(unsigned int, conn->mtu, len);
2864
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002865 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002866 if (!skb)
2867 return NULL;
2868
2869 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002870 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002871
2872 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002873 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002874 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002875 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002876
2877 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2878 cmd->code = code;
2879 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002880 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002881
2882 if (dlen) {
2883 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2884 memcpy(skb_put(skb, count), data, count);
2885 data += count;
2886 }
2887
2888 len -= skb->len;
2889
2890 /* Continuation fragments (no L2CAP header) */
2891 frag = &skb_shinfo(skb)->frag_list;
2892 while (len) {
2893 count = min_t(unsigned int, conn->mtu, len);
2894
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002895 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002896 if (!*frag)
2897 goto fail;
2898
2899 memcpy(skb_put(*frag, count), data, count);
2900
2901 len -= count;
2902 data += count;
2903
2904 frag = &(*frag)->next;
2905 }
2906
2907 return skb;
2908
2909fail:
2910 kfree_skb(skb);
2911 return NULL;
2912}
2913
Gustavo Padovan2d792812012-10-06 10:07:01 +01002914static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2915 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002916{
2917 struct l2cap_conf_opt *opt = *ptr;
2918 int len;
2919
2920 len = L2CAP_CONF_OPT_SIZE + opt->len;
2921 *ptr += len;
2922
2923 *type = opt->type;
2924 *olen = opt->len;
2925
2926 switch (opt->len) {
2927 case 1:
2928 *val = *((u8 *) opt->val);
2929 break;
2930
2931 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002932 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002933 break;
2934
2935 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002936 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002937 break;
2938
2939 default:
2940 *val = (unsigned long) opt->val;
2941 break;
2942 }
2943
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002944 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002945 return len;
2946}
2947
Linus Torvalds1da177e2005-04-16 15:20:36 -07002948static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2949{
2950 struct l2cap_conf_opt *opt = *ptr;
2951
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002952 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953
2954 opt->type = type;
2955 opt->len = len;
2956
2957 switch (len) {
2958 case 1:
2959 *((u8 *) opt->val) = val;
2960 break;
2961
2962 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002963 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002964 break;
2965
2966 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002967 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002968 break;
2969
2970 default:
2971 memcpy(opt->val, (void *) val, len);
2972 break;
2973 }
2974
2975 *ptr += L2CAP_CONF_OPT_SIZE + len;
2976}
2977
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002978static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2979{
2980 struct l2cap_conf_efs efs;
2981
Szymon Janc1ec918c2011-11-16 09:32:21 +01002982 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002983 case L2CAP_MODE_ERTM:
2984 efs.id = chan->local_id;
2985 efs.stype = chan->local_stype;
2986 efs.msdu = cpu_to_le16(chan->local_msdu);
2987 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002988 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002989 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002990 break;
2991
2992 case L2CAP_MODE_STREAMING:
2993 efs.id = 1;
2994 efs.stype = L2CAP_SERV_BESTEFFORT;
2995 efs.msdu = cpu_to_le16(chan->local_msdu);
2996 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2997 efs.acc_lat = 0;
2998 efs.flush_to = 0;
2999 break;
3000
3001 default:
3002 return;
3003 }
3004
3005 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03003006 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003007}
3008
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003009static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003010{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003011 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003012 ack_timer.work);
3013 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003014
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003015 BT_DBG("chan %p", chan);
3016
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003017 l2cap_chan_lock(chan);
3018
Mat Martineau03625202012-05-17 20:53:51 -07003019 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3020 chan->last_acked_seq);
3021
3022 if (frames_to_ack)
3023 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003024
3025 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003026 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003027}
3028
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003029int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003030{
Mat Martineau3c588192012-04-11 10:48:42 -07003031 int err;
3032
Mat Martineau105bdf92012-04-27 16:50:48 -07003033 chan->next_tx_seq = 0;
3034 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003035 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003036 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003037 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003038 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003039 chan->last_acked_seq = 0;
3040 chan->sdu = NULL;
3041 chan->sdu_last_frag = NULL;
3042 chan->sdu_len = 0;
3043
Mat Martineaud34c34f2012-05-14 14:49:27 -07003044 skb_queue_head_init(&chan->tx_q);
3045
Mat Martineau08333282012-10-23 15:24:06 -07003046 chan->local_amp_id = 0;
3047 chan->move_id = 0;
3048 chan->move_state = L2CAP_MOVE_STABLE;
3049 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3050
Mat Martineau105bdf92012-04-27 16:50:48 -07003051 if (chan->mode != L2CAP_MODE_ERTM)
3052 return 0;
3053
3054 chan->rx_state = L2CAP_RX_STATE_RECV;
3055 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003056
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003057 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3058 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3059 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003060
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003061 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003062
Mat Martineau3c588192012-04-11 10:48:42 -07003063 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3064 if (err < 0)
3065 return err;
3066
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003067 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3068 if (err < 0)
3069 l2cap_seq_list_free(&chan->srej_list);
3070
3071 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003072}
3073
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003074static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3075{
3076 switch (mode) {
3077 case L2CAP_MODE_STREAMING:
3078 case L2CAP_MODE_ERTM:
3079 if (l2cap_mode_supported(mode, remote_feat_mask))
3080 return mode;
3081 /* fall through */
3082 default:
3083 return L2CAP_MODE_BASIC;
3084 }
3085}
3086
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003087static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
3088{
3089 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
3090}
3091
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003092static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
3093{
3094 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
3095}
3096
Mat Martineau36c86c82012-10-23 15:24:20 -07003097static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3098 struct l2cap_conf_rfc *rfc)
3099{
3100 if (chan->local_amp_id && chan->hs_hcon) {
3101 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3102
3103 /* Class 1 devices have must have ERTM timeouts
3104 * exceeding the Link Supervision Timeout. The
3105 * default Link Supervision Timeout for AMP
3106 * controllers is 10 seconds.
3107 *
3108 * Class 1 devices use 0xffffffff for their
3109 * best-effort flush timeout, so the clamping logic
3110 * will result in a timeout that meets the above
3111 * requirement. ERTM timeouts are 16-bit values, so
3112 * the maximum timeout is 65.535 seconds.
3113 */
3114
3115 /* Convert timeout to milliseconds and round */
3116 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3117
3118 /* This is the recommended formula for class 2 devices
3119 * that start ERTM timers when packets are sent to the
3120 * controller.
3121 */
3122 ertm_to = 3 * ertm_to + 500;
3123
3124 if (ertm_to > 0xffff)
3125 ertm_to = 0xffff;
3126
3127 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3128 rfc->monitor_timeout = rfc->retrans_timeout;
3129 } else {
3130 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3131 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3132 }
3133}
3134
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003135static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3136{
3137 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003138 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003139 /* use extended control field */
3140 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003141 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3142 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003143 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003144 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003145 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3146 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003147 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003148}
3149
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003150static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003151{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003152 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003153 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003154 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003155 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003156
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003157 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003158
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003159 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003160 goto done;
3161
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003162 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003163 case L2CAP_MODE_STREAMING:
3164 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003165 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003166 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003167
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003168 if (__l2cap_efs_supported(chan))
3169 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3170
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003171 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003172 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003173 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003174 break;
3175 }
3176
3177done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003178 if (chan->imtu != L2CAP_DEFAULT_MTU)
3179 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003180
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003181 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003182 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003183 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003184 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003185 break;
3186
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003187 rfc.mode = L2CAP_MODE_BASIC;
3188 rfc.txwin_size = 0;
3189 rfc.max_transmit = 0;
3190 rfc.retrans_timeout = 0;
3191 rfc.monitor_timeout = 0;
3192 rfc.max_pdu_size = 0;
3193
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003194 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003195 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003196 break;
3197
3198 case L2CAP_MODE_ERTM:
3199 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003200 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003201
3202 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003203
3204 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003205 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3206 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003207 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003208
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003209 l2cap_txwin_setup(chan);
3210
3211 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003212 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003213
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003214 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003215 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003216
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003217 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3218 l2cap_add_opt_efs(&ptr, chan);
3219
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003220 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3221 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003222 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003223
3224 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3225 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003226 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003227 chan->fcs = L2CAP_FCS_NONE;
3228 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3229 chan->fcs);
3230 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003231 break;
3232
3233 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003234 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003235 rfc.mode = L2CAP_MODE_STREAMING;
3236 rfc.txwin_size = 0;
3237 rfc.max_transmit = 0;
3238 rfc.retrans_timeout = 0;
3239 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003240
3241 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003242 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3243 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003244 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003245
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003246 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003247 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003248
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003249 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3250 l2cap_add_opt_efs(&ptr, chan);
3251
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003252 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3253 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003254 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003255 chan->fcs = L2CAP_FCS_NONE;
3256 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3257 chan->fcs);
3258 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003259 break;
3260 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003261
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003262 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003263 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003264
3265 return ptr - data;
3266}
3267
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003268static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003269{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003270 struct l2cap_conf_rsp *rsp = data;
3271 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003272 void *req = chan->conf_req;
3273 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003274 int type, hint, olen;
3275 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003276 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003277 struct l2cap_conf_efs efs;
3278 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003279 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003280 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003281 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003282
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003283 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003284
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003285 while (len >= L2CAP_CONF_OPT_SIZE) {
3286 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003287
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003288 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003289 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003290
3291 switch (type) {
3292 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003293 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003294 break;
3295
3296 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003297 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003298 break;
3299
3300 case L2CAP_CONF_QOS:
3301 break;
3302
Marcel Holtmann6464f352007-10-20 13:39:51 +02003303 case L2CAP_CONF_RFC:
3304 if (olen == sizeof(rfc))
3305 memcpy(&rfc, (void *) val, olen);
3306 break;
3307
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003308 case L2CAP_CONF_FCS:
3309 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003310 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003311 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003312
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003313 case L2CAP_CONF_EFS:
3314 remote_efs = 1;
3315 if (olen == sizeof(efs))
3316 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003317 break;
3318
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003319 case L2CAP_CONF_EWS:
3320 if (!enable_hs)
3321 return -ECONNREFUSED;
3322
3323 set_bit(FLAG_EXT_CTRL, &chan->flags);
3324 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003325 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003326 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003327 break;
3328
3329 default:
3330 if (hint)
3331 break;
3332
3333 result = L2CAP_CONF_UNKNOWN;
3334 *((u8 *) ptr++) = type;
3335 break;
3336 }
3337 }
3338
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003339 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003340 goto done;
3341
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003342 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003343 case L2CAP_MODE_STREAMING:
3344 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003345 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003346 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003347 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003348 break;
3349 }
3350
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003351 if (remote_efs) {
3352 if (__l2cap_efs_supported(chan))
3353 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3354 else
3355 return -ECONNREFUSED;
3356 }
3357
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003358 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003359 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003360
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003361 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003362 }
3363
3364done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003365 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003366 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003367 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003368
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003369 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003370 return -ECONNREFUSED;
3371
Gustavo Padovan2d792812012-10-06 10:07:01 +01003372 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3373 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003374 }
3375
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003376 if (result == L2CAP_CONF_SUCCESS) {
3377 /* Configure output options and let the other side know
3378 * which ones we don't like. */
3379
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003380 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3381 result = L2CAP_CONF_UNACCEPT;
3382 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003383 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003384 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003385 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003386 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003387
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003388 if (remote_efs) {
3389 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003390 efs.stype != L2CAP_SERV_NOTRAFIC &&
3391 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003392
3393 result = L2CAP_CONF_UNACCEPT;
3394
3395 if (chan->num_conf_req >= 1)
3396 return -ECONNREFUSED;
3397
3398 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003399 sizeof(efs),
3400 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003401 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003402 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003403 result = L2CAP_CONF_PENDING;
3404 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003405 }
3406 }
3407
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003408 switch (rfc.mode) {
3409 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003410 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003411 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003412 break;
3413
3414 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003415 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3416 chan->remote_tx_win = rfc.txwin_size;
3417 else
3418 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3419
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003420 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003421
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003422 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003423 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3424 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003425 rfc.max_pdu_size = cpu_to_le16(size);
3426 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003427
Mat Martineau36c86c82012-10-23 15:24:20 -07003428 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003429
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003430 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003431
3432 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003433 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003434
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003435 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3436 chan->remote_id = efs.id;
3437 chan->remote_stype = efs.stype;
3438 chan->remote_msdu = le16_to_cpu(efs.msdu);
3439 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003440 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003441 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003442 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003443 chan->remote_sdu_itime =
3444 le32_to_cpu(efs.sdu_itime);
3445 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003446 sizeof(efs),
3447 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003448 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003449 break;
3450
3451 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003452 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003453 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3454 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003455 rfc.max_pdu_size = cpu_to_le16(size);
3456 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003457
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003458 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003459
Gustavo Padovan2d792812012-10-06 10:07:01 +01003460 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3461 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003462
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003463 break;
3464
3465 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003466 result = L2CAP_CONF_UNACCEPT;
3467
3468 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003469 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003470 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003471
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003472 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003473 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003474 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003475 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003476 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003477 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003478
3479 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003480}
3481
Gustavo Padovan2d792812012-10-06 10:07:01 +01003482static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3483 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003484{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003485 struct l2cap_conf_req *req = data;
3486 void *ptr = req->data;
3487 int type, olen;
3488 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003489 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003490 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003491
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003492 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003493
3494 while (len >= L2CAP_CONF_OPT_SIZE) {
3495 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3496
3497 switch (type) {
3498 case L2CAP_CONF_MTU:
3499 if (val < L2CAP_DEFAULT_MIN_MTU) {
3500 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003501 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003502 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003503 chan->imtu = val;
3504 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003505 break;
3506
3507 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003508 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003509 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003510 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003511 break;
3512
3513 case L2CAP_CONF_RFC:
3514 if (olen == sizeof(rfc))
3515 memcpy(&rfc, (void *)val, olen);
3516
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003517 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003518 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003519 return -ECONNREFUSED;
3520
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003521 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003522
3523 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003524 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003525 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003526
3527 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003528 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003529 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003530 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003531 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003532
3533 case L2CAP_CONF_EFS:
3534 if (olen == sizeof(efs))
3535 memcpy(&efs, (void *)val, olen);
3536
3537 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003538 efs.stype != L2CAP_SERV_NOTRAFIC &&
3539 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003540 return -ECONNREFUSED;
3541
Gustavo Padovan2d792812012-10-06 10:07:01 +01003542 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3543 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003544 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003545
3546 case L2CAP_CONF_FCS:
3547 if (*result == L2CAP_CONF_PENDING)
3548 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003549 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003550 &chan->conf_state);
3551 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003552 }
3553 }
3554
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003555 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003556 return -ECONNREFUSED;
3557
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003558 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003559
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003560 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003561 switch (rfc.mode) {
3562 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003563 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3564 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3565 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003566 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3567 chan->ack_win = min_t(u16, chan->ack_win,
3568 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003569
3570 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3571 chan->local_msdu = le16_to_cpu(efs.msdu);
3572 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003573 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003574 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3575 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003576 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003577 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003578 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003579
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003580 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003581 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003582 }
3583 }
3584
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003585 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003586 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003587
3588 return ptr - data;
3589}
3590
Gustavo Padovan2d792812012-10-06 10:07:01 +01003591static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3592 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003593{
3594 struct l2cap_conf_rsp *rsp = data;
3595 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003596
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003597 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003598
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003599 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003600 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003601 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003602
3603 return ptr - data;
3604}
3605
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003606void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003607{
3608 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003609 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003610 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003611 u8 rsp_code;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003612
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003613 rsp.scid = cpu_to_le16(chan->dcid);
3614 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003615 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3616 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003617
3618 if (chan->hs_hcon)
3619 rsp_code = L2CAP_CREATE_CHAN_RSP;
3620 else
3621 rsp_code = L2CAP_CONN_RSP;
3622
3623 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3624
3625 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003626
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003627 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003628 return;
3629
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003630 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003631 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003632 chan->num_conf_req++;
3633}
3634
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003635static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003636{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003637 int type, olen;
3638 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003639 /* Use sane default values in case a misbehaving remote device
3640 * did not send an RFC or extended window size option.
3641 */
3642 u16 txwin_ext = chan->ack_win;
3643 struct l2cap_conf_rfc rfc = {
3644 .mode = chan->mode,
3645 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3646 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3647 .max_pdu_size = cpu_to_le16(chan->imtu),
3648 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3649 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003650
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003651 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003652
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003653 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003654 return;
3655
3656 while (len >= L2CAP_CONF_OPT_SIZE) {
3657 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3658
Mat Martineauc20f8e32012-07-10 05:47:07 -07003659 switch (type) {
3660 case L2CAP_CONF_RFC:
3661 if (olen == sizeof(rfc))
3662 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003663 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003664 case L2CAP_CONF_EWS:
3665 txwin_ext = val;
3666 break;
3667 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003668 }
3669
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003670 switch (rfc.mode) {
3671 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003672 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3673 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003674 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3675 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3676 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3677 else
3678 chan->ack_win = min_t(u16, chan->ack_win,
3679 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003680 break;
3681 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003682 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003683 }
3684}
3685
Gustavo Padovan2d792812012-10-06 10:07:01 +01003686static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003687 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3688 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003689{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003690 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003691
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003692 if (cmd_len < sizeof(*rej))
3693 return -EPROTO;
3694
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003695 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003696 return 0;
3697
3698 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003699 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003700 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003701
3702 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003703 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003704
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003705 l2cap_conn_start(conn);
3706 }
3707
3708 return 0;
3709}
3710
Mat Martineau17009152012-10-23 15:24:07 -07003711static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3712 struct l2cap_cmd_hdr *cmd,
3713 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003714{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003715 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3716 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003717 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003718 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003719 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003720
3721 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003722 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003723
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003724 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003725
3726 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003727 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003728 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003729 result = L2CAP_CR_BAD_PSM;
3730 goto sendresp;
3731 }
3732
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003733 parent = pchan->sk;
3734
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003735 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003736 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003737
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003738 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003739 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003740 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003741 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003742 result = L2CAP_CR_SEC_BLOCK;
3743 goto response;
3744 }
3745
Linus Torvalds1da177e2005-04-16 15:20:36 -07003746 result = L2CAP_CR_NO_MEM;
3747
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003748 /* Check if we already have channel with that dcid */
3749 if (__l2cap_get_chan_by_dcid(conn, scid))
3750 goto response;
3751
Gustavo Padovan80b98022012-05-27 22:27:51 -03003752 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003753 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003754 goto response;
3755
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003756 sk = chan->sk;
3757
Linus Torvalds1da177e2005-04-16 15:20:36 -07003758 bacpy(&bt_sk(sk)->src, conn->src);
3759 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003760 chan->psm = psm;
3761 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003762 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003763
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003764 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003765
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003766 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003767
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003768 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003769
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003770 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003771
Marcel Holtmann984947d2009-02-06 23:35:19 +01003772 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003773 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003774 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003775 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003776 result = L2CAP_CR_PEND;
3777 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003778 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003779 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003780 /* Force pending result for AMP controllers.
3781 * The connection will succeed after the
3782 * physical link is up.
3783 */
3784 if (amp_id) {
3785 __l2cap_state_change(chan, BT_CONNECT2);
3786 result = L2CAP_CR_PEND;
3787 } else {
3788 __l2cap_state_change(chan, BT_CONFIG);
3789 result = L2CAP_CR_SUCCESS;
3790 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003791 status = L2CAP_CS_NO_INFO;
3792 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003793 } 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_AUTHEN_PEND;
3797 }
3798 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003799 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003800 result = L2CAP_CR_PEND;
3801 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003802 }
3803
Linus Torvalds1da177e2005-04-16 15:20:36 -07003804response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003805 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003806 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003807
3808sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003809 rsp.scid = cpu_to_le16(scid);
3810 rsp.dcid = cpu_to_le16(dcid);
3811 rsp.result = cpu_to_le16(result);
3812 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003813 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003814
3815 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3816 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003817 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003818
3819 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3820 conn->info_ident = l2cap_get_ident(conn);
3821
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003822 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003823
Gustavo Padovan2d792812012-10-06 10:07:01 +01003824 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3825 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003826 }
3827
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003828 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003829 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003830 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003831 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003832 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003833 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003834 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003835 }
Mat Martineau17009152012-10-23 15:24:07 -07003836
3837 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003838}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003839
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003840static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003841 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003842{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303843 struct hci_dev *hdev = conn->hcon->hdev;
3844 struct hci_conn *hcon = conn->hcon;
3845
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003846 if (cmd_len < sizeof(struct l2cap_conn_req))
3847 return -EPROTO;
3848
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303849 hci_dev_lock(hdev);
3850 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3851 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3852 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3853 hcon->dst_type, 0, NULL, 0,
3854 hcon->dev_class);
3855 hci_dev_unlock(hdev);
3856
Gustavo Padovan300229f2012-10-12 19:40:40 +08003857 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003858 return 0;
3859}
3860
Mat Martineau5909cf32012-10-23 15:24:08 -07003861static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003862 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3863 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003864{
3865 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3866 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003867 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003868 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003869 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003870
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003871 if (cmd_len < sizeof(*rsp))
3872 return -EPROTO;
3873
Linus Torvalds1da177e2005-04-16 15:20:36 -07003874 scid = __le16_to_cpu(rsp->scid);
3875 dcid = __le16_to_cpu(rsp->dcid);
3876 result = __le16_to_cpu(rsp->result);
3877 status = __le16_to_cpu(rsp->status);
3878
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003879 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 +01003880 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003881
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003882 mutex_lock(&conn->chan_lock);
3883
Linus Torvalds1da177e2005-04-16 15:20:36 -07003884 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003885 chan = __l2cap_get_chan_by_scid(conn, scid);
3886 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003887 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003888 goto unlock;
3889 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003890 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003891 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3892 if (!chan) {
Johan Hedberg21870b52013-09-16 13:05:14 +03003893 err = -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003894 goto unlock;
3895 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003896 }
3897
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003898 err = 0;
3899
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003900 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003901
Linus Torvalds1da177e2005-04-16 15:20:36 -07003902 switch (result) {
3903 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003904 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003905 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003906 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003907 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003908
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003909 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003910 break;
3911
Linus Torvalds1da177e2005-04-16 15:20:36 -07003912 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003913 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003914 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003915 break;
3916
3917 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003918 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003919 break;
3920
3921 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003922 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003923 break;
3924 }
3925
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003926 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003927
3928unlock:
3929 mutex_unlock(&conn->chan_lock);
3930
3931 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003932}
3933
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003934static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003935{
3936 /* FCS is enabled only in ERTM or streaming mode, if one or both
3937 * sides request it.
3938 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003939 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003940 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003941 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003942 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003943}
3944
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003945static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3946 u8 ident, u16 flags)
3947{
3948 struct l2cap_conn *conn = chan->conn;
3949
3950 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3951 flags);
3952
3953 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3954 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3955
3956 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
3957 l2cap_build_conf_rsp(chan, data,
3958 L2CAP_CONF_SUCCESS, flags), data);
3959}
3960
Gustavo Padovan2d792812012-10-06 10:07:01 +01003961static inline int l2cap_config_req(struct l2cap_conn *conn,
3962 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3963 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003964{
3965 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3966 u16 dcid, flags;
3967 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003968 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003969 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003970
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003971 if (cmd_len < sizeof(*req))
3972 return -EPROTO;
3973
Linus Torvalds1da177e2005-04-16 15:20:36 -07003974 dcid = __le16_to_cpu(req->dcid);
3975 flags = __le16_to_cpu(req->flags);
3976
3977 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3978
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003979 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003980 if (!chan)
Johan Hedberg21870b52013-09-16 13:05:14 +03003981 return -EBADSLT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003982
David S. Miller033b1142011-07-21 13:38:42 -07003983 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003984 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003985
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003986 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003987 rej.scid = cpu_to_le16(chan->scid);
3988 rej.dcid = cpu_to_le16(chan->dcid);
3989
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003990 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003991 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003992 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003993 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003994
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003995 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003996 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003997 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003998 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003999 l2cap_build_conf_rsp(chan, rsp,
4000 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004001 goto unlock;
4002 }
4003
4004 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004005 memcpy(chan->conf_req + chan->conf_len, req->data, len);
4006 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004007
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004008 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004009 /* Incomplete config. Send empty response. */
4010 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004011 l2cap_build_conf_rsp(chan, rsp,
4012 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004013 goto unlock;
4014 }
4015
4016 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004017 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004018 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004019 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004020 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004021 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004022
Mat Martineau1500109b2012-10-23 15:24:15 -07004023 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004024 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004025 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004026
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004027 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004028 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004029
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004030 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004031 goto unlock;
4032
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004033 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004034 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004035
Mat Martineau105bdf92012-04-27 16:50:48 -07004036 if (chan->mode == L2CAP_MODE_ERTM ||
4037 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004038 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004039
Mat Martineau3c588192012-04-11 10:48:42 -07004040 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004041 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004042 else
4043 l2cap_chan_ready(chan);
4044
Marcel Holtmann876d9482007-10-20 13:35:42 +02004045 goto unlock;
4046 }
4047
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004048 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004049 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004050 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004051 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004052 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004053 }
4054
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004055 /* Got Conf Rsp PENDING from remote side and asume we sent
4056 Conf Rsp PENDING in the code above */
4057 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004058 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004059
4060 /* check compatibility */
4061
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004062 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004063 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004064 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4065 else
4066 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004067 }
4068
Linus Torvalds1da177e2005-04-16 15:20:36 -07004069unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004070 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004071 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004072}
4073
Gustavo Padovan2d792812012-10-06 10:07:01 +01004074static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004075 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4076 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004077{
4078 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4079 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004080 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004081 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004082 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004083
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004084 if (cmd_len < sizeof(*rsp))
4085 return -EPROTO;
4086
Linus Torvalds1da177e2005-04-16 15:20:36 -07004087 scid = __le16_to_cpu(rsp->scid);
4088 flags = __le16_to_cpu(rsp->flags);
4089 result = __le16_to_cpu(rsp->result);
4090
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004091 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4092 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004093
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004094 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004095 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004096 return 0;
4097
4098 switch (result) {
4099 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004100 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004101 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004102 break;
4103
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004104 case L2CAP_CONF_PENDING:
4105 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4106
4107 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4108 char buf[64];
4109
4110 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004111 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004112 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004113 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004114 goto done;
4115 }
4116
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004117 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004118 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4119 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004120 } else {
4121 if (l2cap_check_efs(chan)) {
4122 amp_create_logical_link(chan);
4123 chan->ident = cmd->ident;
4124 }
4125 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004126 }
4127 goto done;
4128
Linus Torvalds1da177e2005-04-16 15:20:36 -07004129 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004130 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004131 char req[64];
4132
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004133 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004134 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004135 goto done;
4136 }
4137
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004138 /* throw out any old stored conf requests */
4139 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004140 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004141 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004142 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004143 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004144 goto done;
4145 }
4146
4147 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004148 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004149 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004150 if (result != L2CAP_CONF_SUCCESS)
4151 goto done;
4152 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004153 }
4154
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004155 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004156 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004157
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004158 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004159 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004160 goto done;
4161 }
4162
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004163 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004164 goto done;
4165
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004166 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004167
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004168 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004169 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004170
Mat Martineau105bdf92012-04-27 16:50:48 -07004171 if (chan->mode == L2CAP_MODE_ERTM ||
4172 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004173 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004174
Mat Martineau3c588192012-04-11 10:48:42 -07004175 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004176 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004177 else
4178 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004179 }
4180
4181done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004182 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004183 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004184}
4185
Gustavo Padovan2d792812012-10-06 10:07:01 +01004186static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004187 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4188 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004189{
4190 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4191 struct l2cap_disconn_rsp rsp;
4192 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004193 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004194 struct sock *sk;
4195
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004196 if (cmd_len != sizeof(*req))
4197 return -EPROTO;
4198
Linus Torvalds1da177e2005-04-16 15:20:36 -07004199 scid = __le16_to_cpu(req->scid);
4200 dcid = __le16_to_cpu(req->dcid);
4201
4202 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4203
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004204 mutex_lock(&conn->chan_lock);
4205
4206 chan = __l2cap_get_chan_by_scid(conn, dcid);
4207 if (!chan) {
4208 mutex_unlock(&conn->chan_lock);
Johan Hedbergc4ea2492013-09-16 13:05:15 +03004209 return -EBADSLT;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004210 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004211
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004212 l2cap_chan_lock(chan);
4213
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004214 sk = chan->sk;
4215
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004216 rsp.dcid = cpu_to_le16(chan->scid);
4217 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004218 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4219
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004220 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004221 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004222 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004223
Mat Martineau61d6ef32012-04-27 16:50:50 -07004224 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004225 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004226
4227 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004228
Gustavo Padovan80b98022012-05-27 22:27:51 -03004229 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004230 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004231
4232 mutex_unlock(&conn->chan_lock);
4233
Linus Torvalds1da177e2005-04-16 15:20:36 -07004234 return 0;
4235}
4236
Gustavo Padovan2d792812012-10-06 10:07:01 +01004237static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004238 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4239 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004240{
4241 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4242 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004243 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004244
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004245 if (cmd_len != sizeof(*rsp))
4246 return -EPROTO;
4247
Linus Torvalds1da177e2005-04-16 15:20:36 -07004248 scid = __le16_to_cpu(rsp->scid);
4249 dcid = __le16_to_cpu(rsp->dcid);
4250
4251 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4252
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004253 mutex_lock(&conn->chan_lock);
4254
4255 chan = __l2cap_get_chan_by_scid(conn, scid);
4256 if (!chan) {
4257 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004258 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004259 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004260
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004261 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004262
Mat Martineau61d6ef32012-04-27 16:50:50 -07004263 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004264 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004265
4266 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004267
Gustavo Padovan80b98022012-05-27 22:27:51 -03004268 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004269 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004270
4271 mutex_unlock(&conn->chan_lock);
4272
Linus Torvalds1da177e2005-04-16 15:20:36 -07004273 return 0;
4274}
4275
Gustavo Padovan2d792812012-10-06 10:07:01 +01004276static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004277 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4278 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004279{
4280 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004281 u16 type;
4282
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004283 if (cmd_len != sizeof(*req))
4284 return -EPROTO;
4285
Linus Torvalds1da177e2005-04-16 15:20:36 -07004286 type = __le16_to_cpu(req->type);
4287
4288 BT_DBG("type 0x%4.4x", type);
4289
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004290 if (type == L2CAP_IT_FEAT_MASK) {
4291 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004292 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004293 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004294 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4295 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004296 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004297 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004298 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004299 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004300 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004301 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004302
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004303 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004304 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4305 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004306 } else if (type == L2CAP_IT_FIXED_CHAN) {
4307 u8 buf[12];
4308 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004309
4310 if (enable_hs)
4311 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4312 else
4313 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4314
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004315 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4316 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004317 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004318 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4319 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004320 } else {
4321 struct l2cap_info_rsp rsp;
4322 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004323 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004324 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4325 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004326 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004327
4328 return 0;
4329}
4330
Gustavo Padovan2d792812012-10-06 10:07:01 +01004331static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004332 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4333 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004334{
4335 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4336 u16 type, result;
4337
Jaganath Kanakkassery3f6fa3d2013-06-21 19:55:11 +05304338 if (cmd_len < sizeof(*rsp))
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004339 return -EPROTO;
4340
Linus Torvalds1da177e2005-04-16 15:20:36 -07004341 type = __le16_to_cpu(rsp->type);
4342 result = __le16_to_cpu(rsp->result);
4343
4344 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4345
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004346 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4347 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004348 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004349 return 0;
4350
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004351 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004352
Ville Tervoadb08ed2010-08-04 09:43:33 +03004353 if (result != L2CAP_IR_SUCCESS) {
4354 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4355 conn->info_ident = 0;
4356
4357 l2cap_conn_start(conn);
4358
4359 return 0;
4360 }
4361
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004362 switch (type) {
4363 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004364 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004365
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004366 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004367 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004368 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004369
4370 conn->info_ident = l2cap_get_ident(conn);
4371
4372 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004373 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004374 } else {
4375 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4376 conn->info_ident = 0;
4377
4378 l2cap_conn_start(conn);
4379 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004380 break;
4381
4382 case L2CAP_IT_FIXED_CHAN:
4383 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004384 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004385 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004386
4387 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004388 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004389 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004390
Linus Torvalds1da177e2005-04-16 15:20:36 -07004391 return 0;
4392}
4393
Mat Martineau17009152012-10-23 15:24:07 -07004394static int l2cap_create_channel_req(struct l2cap_conn *conn,
4395 struct l2cap_cmd_hdr *cmd,
4396 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004397{
4398 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004399 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004400 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004401 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004402 u16 psm, scid;
4403
4404 if (cmd_len != sizeof(*req))
4405 return -EPROTO;
4406
4407 if (!enable_hs)
4408 return -EINVAL;
4409
4410 psm = le16_to_cpu(req->psm);
4411 scid = le16_to_cpu(req->scid);
4412
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004413 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 -07004414
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004415 /* For controller id 0 make BR/EDR connection */
4416 if (req->amp_id == HCI_BREDR_ID) {
4417 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4418 req->amp_id);
4419 return 0;
4420 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004421
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004422 /* Validate AMP controller id */
4423 hdev = hci_dev_get(req->amp_id);
4424 if (!hdev)
4425 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004426
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004427 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004428 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004429 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004430 }
4431
4432 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4433 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004434 if (chan) {
4435 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4436 struct hci_conn *hs_hcon;
4437
4438 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, conn->dst);
4439 if (!hs_hcon) {
4440 hci_dev_put(hdev);
Johan Hedberg21870b52013-09-16 13:05:14 +03004441 return -EBADSLT;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004442 }
4443
4444 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4445
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004446 mgr->bredr_chan = chan;
4447 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004448 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004449 conn->mtu = hdev->block_mtu;
4450 }
4451
4452 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004453
4454 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004455
4456error:
4457 rsp.dcid = 0;
4458 rsp.scid = cpu_to_le16(scid);
4459 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4460 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4461
4462 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4463 sizeof(rsp), &rsp);
4464
Johan Hedbergdc280802013-09-16 13:05:13 +03004465 return 0;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004466}
4467
Mat Martineau8eb200b2012-10-23 15:24:17 -07004468static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4469{
4470 struct l2cap_move_chan_req req;
4471 u8 ident;
4472
4473 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4474
4475 ident = l2cap_get_ident(chan->conn);
4476 chan->ident = ident;
4477
4478 req.icid = cpu_to_le16(chan->scid);
4479 req.dest_amp_id = dest_amp_id;
4480
4481 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4482 &req);
4483
4484 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4485}
4486
Mat Martineau1500109b2012-10-23 15:24:15 -07004487static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004488{
4489 struct l2cap_move_chan_rsp rsp;
4490
Mat Martineau1500109b2012-10-23 15:24:15 -07004491 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004492
Mat Martineau1500109b2012-10-23 15:24:15 -07004493 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004494 rsp.result = cpu_to_le16(result);
4495
Mat Martineau1500109b2012-10-23 15:24:15 -07004496 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4497 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004498}
4499
Mat Martineau5b155ef2012-10-23 15:24:14 -07004500static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004501{
4502 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004503
Mat Martineau5b155ef2012-10-23 15:24:14 -07004504 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004505
Mat Martineau5b155ef2012-10-23 15:24:14 -07004506 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004507
Mat Martineau5b155ef2012-10-23 15:24:14 -07004508 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004509 cfm.result = cpu_to_le16(result);
4510
Mat Martineau5b155ef2012-10-23 15:24:14 -07004511 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4512 sizeof(cfm), &cfm);
4513
4514 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4515}
4516
4517static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4518{
4519 struct l2cap_move_chan_cfm cfm;
4520
4521 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4522
4523 cfm.icid = cpu_to_le16(icid);
4524 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4525
4526 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4527 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004528}
4529
4530static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004531 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004532{
4533 struct l2cap_move_chan_cfm_rsp rsp;
4534
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004535 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004536
4537 rsp.icid = cpu_to_le16(icid);
4538 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4539}
4540
Mat Martineau5f3847a2012-10-23 15:24:12 -07004541static void __release_logical_link(struct l2cap_chan *chan)
4542{
4543 chan->hs_hchan = NULL;
4544 chan->hs_hcon = NULL;
4545
4546 /* Placeholder - release the logical link */
4547}
4548
Mat Martineau1500109b2012-10-23 15:24:15 -07004549static void l2cap_logical_fail(struct l2cap_chan *chan)
4550{
4551 /* Logical link setup failed */
4552 if (chan->state != BT_CONNECTED) {
4553 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004554 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004555 return;
4556 }
4557
4558 switch (chan->move_role) {
4559 case L2CAP_MOVE_ROLE_RESPONDER:
4560 l2cap_move_done(chan);
4561 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4562 break;
4563 case L2CAP_MOVE_ROLE_INITIATOR:
4564 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4565 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4566 /* Remote has only sent pending or
4567 * success responses, clean up
4568 */
4569 l2cap_move_done(chan);
4570 }
4571
4572 /* Other amp move states imply that the move
4573 * has already aborted
4574 */
4575 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4576 break;
4577 }
4578}
4579
4580static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4581 struct hci_chan *hchan)
4582{
4583 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004584
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004585 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004586 chan->hs_hcon->l2cap_data = chan->conn;
4587
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004588 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004589
4590 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004591 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004592
4593 set_default_fcs(chan);
4594
4595 err = l2cap_ertm_init(chan);
4596 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004597 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004598 else
4599 l2cap_chan_ready(chan);
4600 }
4601}
4602
4603static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4604 struct hci_chan *hchan)
4605{
4606 chan->hs_hcon = hchan->conn;
4607 chan->hs_hcon->l2cap_data = chan->conn;
4608
4609 BT_DBG("move_state %d", chan->move_state);
4610
4611 switch (chan->move_state) {
4612 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4613 /* Move confirm will be sent after a success
4614 * response is received
4615 */
4616 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4617 break;
4618 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4619 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4620 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4621 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4622 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4623 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4624 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4625 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4626 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4627 }
4628 break;
4629 default:
4630 /* Move was not in expected state, free the channel */
4631 __release_logical_link(chan);
4632
4633 chan->move_state = L2CAP_MOVE_STABLE;
4634 }
4635}
4636
4637/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004638void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4639 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004640{
Mat Martineau1500109b2012-10-23 15:24:15 -07004641 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4642
4643 if (status) {
4644 l2cap_logical_fail(chan);
4645 __release_logical_link(chan);
4646 return;
4647 }
4648
4649 if (chan->state != BT_CONNECTED) {
4650 /* Ignore logical link if channel is on BR/EDR */
4651 if (chan->local_amp_id)
4652 l2cap_logical_finish_create(chan, hchan);
4653 } else {
4654 l2cap_logical_finish_move(chan, hchan);
4655 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004656}
4657
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004658void l2cap_move_start(struct l2cap_chan *chan)
4659{
4660 BT_DBG("chan %p", chan);
4661
4662 if (chan->local_amp_id == HCI_BREDR_ID) {
4663 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4664 return;
4665 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4666 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4667 /* Placeholder - start physical link setup */
4668 } else {
4669 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4670 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4671 chan->move_id = 0;
4672 l2cap_move_setup(chan);
4673 l2cap_send_move_chan_req(chan, 0);
4674 }
4675}
4676
Mat Martineau8eb200b2012-10-23 15:24:17 -07004677static void l2cap_do_create(struct l2cap_chan *chan, int result,
4678 u8 local_amp_id, u8 remote_amp_id)
4679{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004680 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4681 local_amp_id, remote_amp_id);
4682
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004683 chan->fcs = L2CAP_FCS_NONE;
4684
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004685 /* Outgoing channel on AMP */
4686 if (chan->state == BT_CONNECT) {
4687 if (result == L2CAP_CR_SUCCESS) {
4688 chan->local_amp_id = local_amp_id;
4689 l2cap_send_create_chan_req(chan, remote_amp_id);
4690 } else {
4691 /* Revert to BR/EDR connect */
4692 l2cap_send_conn_req(chan);
4693 }
4694
4695 return;
4696 }
4697
4698 /* Incoming channel on AMP */
4699 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004700 struct l2cap_conn_rsp rsp;
4701 char buf[128];
4702 rsp.scid = cpu_to_le16(chan->dcid);
4703 rsp.dcid = cpu_to_le16(chan->scid);
4704
Mat Martineau8eb200b2012-10-23 15:24:17 -07004705 if (result == L2CAP_CR_SUCCESS) {
4706 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004707 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4708 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004709 } else {
4710 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004711 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4712 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004713 }
4714
4715 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4716 sizeof(rsp), &rsp);
4717
4718 if (result == L2CAP_CR_SUCCESS) {
4719 __l2cap_state_change(chan, BT_CONFIG);
4720 set_bit(CONF_REQ_SENT, &chan->conf_state);
4721 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4722 L2CAP_CONF_REQ,
4723 l2cap_build_conf_req(chan, buf), buf);
4724 chan->num_conf_req++;
4725 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004726 }
4727}
4728
4729static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4730 u8 remote_amp_id)
4731{
4732 l2cap_move_setup(chan);
4733 chan->move_id = local_amp_id;
4734 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4735
4736 l2cap_send_move_chan_req(chan, remote_amp_id);
4737}
4738
4739static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4740{
4741 struct hci_chan *hchan = NULL;
4742
4743 /* Placeholder - get hci_chan for logical link */
4744
4745 if (hchan) {
4746 if (hchan->state == BT_CONNECTED) {
4747 /* Logical link is ready to go */
4748 chan->hs_hcon = hchan->conn;
4749 chan->hs_hcon->l2cap_data = chan->conn;
4750 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4751 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4752
4753 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4754 } else {
4755 /* Wait for logical link to be ready */
4756 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4757 }
4758 } else {
4759 /* Logical link not available */
4760 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4761 }
4762}
4763
4764static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4765{
4766 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4767 u8 rsp_result;
4768 if (result == -EINVAL)
4769 rsp_result = L2CAP_MR_BAD_ID;
4770 else
4771 rsp_result = L2CAP_MR_NOT_ALLOWED;
4772
4773 l2cap_send_move_chan_rsp(chan, rsp_result);
4774 }
4775
4776 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4777 chan->move_state = L2CAP_MOVE_STABLE;
4778
4779 /* Restart data transmission */
4780 l2cap_ertm_send(chan);
4781}
4782
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004783/* Invoke with locked chan */
4784void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004785{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004786 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004787 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004788
Mat Martineau8eb200b2012-10-23 15:24:17 -07004789 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4790 chan, result, local_amp_id, remote_amp_id);
4791
Mat Martineau8eb200b2012-10-23 15:24:17 -07004792 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4793 l2cap_chan_unlock(chan);
4794 return;
4795 }
4796
4797 if (chan->state != BT_CONNECTED) {
4798 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4799 } else if (result != L2CAP_MR_SUCCESS) {
4800 l2cap_do_move_cancel(chan, result);
4801 } else {
4802 switch (chan->move_role) {
4803 case L2CAP_MOVE_ROLE_INITIATOR:
4804 l2cap_do_move_initiate(chan, local_amp_id,
4805 remote_amp_id);
4806 break;
4807 case L2CAP_MOVE_ROLE_RESPONDER:
4808 l2cap_do_move_respond(chan, result);
4809 break;
4810 default:
4811 l2cap_do_move_cancel(chan, result);
4812 break;
4813 }
4814 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004815}
4816
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004817static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004818 struct l2cap_cmd_hdr *cmd,
4819 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004820{
4821 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004822 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004823 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004824 u16 icid = 0;
4825 u16 result = L2CAP_MR_NOT_ALLOWED;
4826
4827 if (cmd_len != sizeof(*req))
4828 return -EPROTO;
4829
4830 icid = le16_to_cpu(req->icid);
4831
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004832 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004833
4834 if (!enable_hs)
4835 return -EINVAL;
4836
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004837 chan = l2cap_get_chan_by_dcid(conn, icid);
4838 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004839 rsp.icid = cpu_to_le16(icid);
4840 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4841 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4842 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004843 return 0;
4844 }
4845
Mat Martineau1500109b2012-10-23 15:24:15 -07004846 chan->ident = cmd->ident;
4847
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004848 if (chan->scid < L2CAP_CID_DYN_START ||
4849 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4850 (chan->mode != L2CAP_MODE_ERTM &&
4851 chan->mode != L2CAP_MODE_STREAMING)) {
4852 result = L2CAP_MR_NOT_ALLOWED;
4853 goto send_move_response;
4854 }
4855
4856 if (chan->local_amp_id == req->dest_amp_id) {
4857 result = L2CAP_MR_SAME_ID;
4858 goto send_move_response;
4859 }
4860
4861 if (req->dest_amp_id) {
4862 struct hci_dev *hdev;
4863 hdev = hci_dev_get(req->dest_amp_id);
4864 if (!hdev || hdev->dev_type != HCI_AMP ||
4865 !test_bit(HCI_UP, &hdev->flags)) {
4866 if (hdev)
4867 hci_dev_put(hdev);
4868
4869 result = L2CAP_MR_BAD_ID;
4870 goto send_move_response;
4871 }
4872 hci_dev_put(hdev);
4873 }
4874
4875 /* Detect a move collision. Only send a collision response
4876 * if this side has "lost", otherwise proceed with the move.
4877 * The winner has the larger bd_addr.
4878 */
4879 if ((__chan_is_moving(chan) ||
4880 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
4881 bacmp(conn->src, conn->dst) > 0) {
4882 result = L2CAP_MR_COLLISION;
4883 goto send_move_response;
4884 }
4885
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004886 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4887 l2cap_move_setup(chan);
4888 chan->move_id = req->dest_amp_id;
4889 icid = chan->dcid;
4890
4891 if (!req->dest_amp_id) {
4892 /* Moving to BR/EDR */
4893 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4894 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4895 result = L2CAP_MR_PEND;
4896 } else {
4897 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4898 result = L2CAP_MR_SUCCESS;
4899 }
4900 } else {
4901 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4902 /* Placeholder - uncomment when amp functions are available */
4903 /*amp_accept_physical(chan, req->dest_amp_id);*/
4904 result = L2CAP_MR_PEND;
4905 }
4906
4907send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004908 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004909
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004910 l2cap_chan_unlock(chan);
4911
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004912 return 0;
4913}
4914
Mat Martineau5b155ef2012-10-23 15:24:14 -07004915static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4916{
4917 struct l2cap_chan *chan;
4918 struct hci_chan *hchan = NULL;
4919
4920 chan = l2cap_get_chan_by_scid(conn, icid);
4921 if (!chan) {
4922 l2cap_send_move_chan_cfm_icid(conn, icid);
4923 return;
4924 }
4925
4926 __clear_chan_timer(chan);
4927 if (result == L2CAP_MR_PEND)
4928 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4929
4930 switch (chan->move_state) {
4931 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4932 /* Move confirm will be sent when logical link
4933 * is complete.
4934 */
4935 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4936 break;
4937 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4938 if (result == L2CAP_MR_PEND) {
4939 break;
4940 } else if (test_bit(CONN_LOCAL_BUSY,
4941 &chan->conn_state)) {
4942 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4943 } else {
4944 /* Logical link is up or moving to BR/EDR,
4945 * proceed with move
4946 */
4947 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4948 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4949 }
4950 break;
4951 case L2CAP_MOVE_WAIT_RSP:
4952 /* Moving to AMP */
4953 if (result == L2CAP_MR_SUCCESS) {
4954 /* Remote is ready, send confirm immediately
4955 * after logical link is ready
4956 */
4957 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4958 } else {
4959 /* Both logical link and move success
4960 * are required to confirm
4961 */
4962 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
4963 }
4964
4965 /* Placeholder - get hci_chan for logical link */
4966 if (!hchan) {
4967 /* Logical link not available */
4968 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4969 break;
4970 }
4971
4972 /* If the logical link is not yet connected, do not
4973 * send confirmation.
4974 */
4975 if (hchan->state != BT_CONNECTED)
4976 break;
4977
4978 /* Logical link is already ready to go */
4979
4980 chan->hs_hcon = hchan->conn;
4981 chan->hs_hcon->l2cap_data = chan->conn;
4982
4983 if (result == L2CAP_MR_SUCCESS) {
4984 /* Can confirm now */
4985 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4986 } else {
4987 /* Now only need move success
4988 * to confirm
4989 */
4990 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4991 }
4992
4993 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4994 break;
4995 default:
4996 /* Any other amp move state means the move failed. */
4997 chan->move_id = chan->local_amp_id;
4998 l2cap_move_done(chan);
4999 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5000 }
5001
5002 l2cap_chan_unlock(chan);
5003}
5004
5005static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
5006 u16 result)
5007{
5008 struct l2cap_chan *chan;
5009
5010 chan = l2cap_get_chan_by_ident(conn, ident);
5011 if (!chan) {
5012 /* Could not locate channel, icid is best guess */
5013 l2cap_send_move_chan_cfm_icid(conn, icid);
5014 return;
5015 }
5016
5017 __clear_chan_timer(chan);
5018
5019 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5020 if (result == L2CAP_MR_COLLISION) {
5021 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5022 } else {
5023 /* Cleanup - cancel move */
5024 chan->move_id = chan->local_amp_id;
5025 l2cap_move_done(chan);
5026 }
5027 }
5028
5029 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5030
5031 l2cap_chan_unlock(chan);
5032}
5033
5034static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5035 struct l2cap_cmd_hdr *cmd,
5036 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005037{
5038 struct l2cap_move_chan_rsp *rsp = data;
5039 u16 icid, result;
5040
5041 if (cmd_len != sizeof(*rsp))
5042 return -EPROTO;
5043
5044 icid = le16_to_cpu(rsp->icid);
5045 result = le16_to_cpu(rsp->result);
5046
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005047 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005048
Mat Martineau5b155ef2012-10-23 15:24:14 -07005049 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5050 l2cap_move_continue(conn, icid, result);
5051 else
5052 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005053
5054 return 0;
5055}
5056
Mat Martineau5f3847a2012-10-23 15:24:12 -07005057static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5058 struct l2cap_cmd_hdr *cmd,
5059 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005060{
5061 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005062 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005063 u16 icid, result;
5064
5065 if (cmd_len != sizeof(*cfm))
5066 return -EPROTO;
5067
5068 icid = le16_to_cpu(cfm->icid);
5069 result = le16_to_cpu(cfm->result);
5070
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005071 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005072
Mat Martineau5f3847a2012-10-23 15:24:12 -07005073 chan = l2cap_get_chan_by_dcid(conn, icid);
5074 if (!chan) {
5075 /* Spec requires a response even if the icid was not found */
5076 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5077 return 0;
5078 }
5079
5080 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5081 if (result == L2CAP_MC_CONFIRMED) {
5082 chan->local_amp_id = chan->move_id;
5083 if (!chan->local_amp_id)
5084 __release_logical_link(chan);
5085 } else {
5086 chan->move_id = chan->local_amp_id;
5087 }
5088
5089 l2cap_move_done(chan);
5090 }
5091
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005092 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5093
Mat Martineau5f3847a2012-10-23 15:24:12 -07005094 l2cap_chan_unlock(chan);
5095
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005096 return 0;
5097}
5098
5099static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005100 struct l2cap_cmd_hdr *cmd,
5101 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005102{
5103 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005104 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005105 u16 icid;
5106
5107 if (cmd_len != sizeof(*rsp))
5108 return -EPROTO;
5109
5110 icid = le16_to_cpu(rsp->icid);
5111
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005112 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005113
Mat Martineau3fd71a02012-10-23 15:24:16 -07005114 chan = l2cap_get_chan_by_scid(conn, icid);
5115 if (!chan)
5116 return 0;
5117
5118 __clear_chan_timer(chan);
5119
5120 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5121 chan->local_amp_id = chan->move_id;
5122
5123 if (!chan->local_amp_id && chan->hs_hchan)
5124 __release_logical_link(chan);
5125
5126 l2cap_move_done(chan);
5127 }
5128
5129 l2cap_chan_unlock(chan);
5130
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005131 return 0;
5132}
5133
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005134static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005135 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005136{
5137 u16 max_latency;
5138
5139 if (min > max || min < 6 || max > 3200)
5140 return -EINVAL;
5141
5142 if (to_multiplier < 10 || to_multiplier > 3200)
5143 return -EINVAL;
5144
5145 if (max >= to_multiplier * 8)
5146 return -EINVAL;
5147
5148 max_latency = (to_multiplier * 8 / max) - 1;
5149 if (latency > 499 || latency > max_latency)
5150 return -EINVAL;
5151
5152 return 0;
5153}
5154
5155static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005156 struct l2cap_cmd_hdr *cmd,
5157 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005158{
5159 struct hci_conn *hcon = conn->hcon;
5160 struct l2cap_conn_param_update_req *req;
5161 struct l2cap_conn_param_update_rsp rsp;
5162 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005163 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005164
5165 if (!(hcon->link_mode & HCI_LM_MASTER))
5166 return -EINVAL;
5167
5168 cmd_len = __le16_to_cpu(cmd->len);
5169 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5170 return -EPROTO;
5171
5172 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005173 min = __le16_to_cpu(req->min);
5174 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005175 latency = __le16_to_cpu(req->latency);
5176 to_multiplier = __le16_to_cpu(req->to_multiplier);
5177
5178 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 +01005179 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005180
5181 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005182
5183 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5184 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005185 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005186 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005187 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005188
5189 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005190 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005191
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005192 if (!err)
5193 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5194
Claudio Takahaside731152011-02-11 19:28:55 -02005195 return 0;
5196}
5197
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005198static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005199 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5200 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005201{
5202 int err = 0;
5203
5204 switch (cmd->code) {
5205 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005206 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005207 break;
5208
5209 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005210 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005211 break;
5212
5213 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005214 case L2CAP_CREATE_CHAN_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005215 err = l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005216 break;
5217
5218 case L2CAP_CONF_REQ:
5219 err = l2cap_config_req(conn, cmd, cmd_len, data);
5220 break;
5221
5222 case L2CAP_CONF_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005223 err = l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005224 break;
5225
5226 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005227 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005228 break;
5229
5230 case L2CAP_DISCONN_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005231 err = l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005232 break;
5233
5234 case L2CAP_ECHO_REQ:
5235 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5236 break;
5237
5238 case L2CAP_ECHO_RSP:
5239 break;
5240
5241 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005242 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005243 break;
5244
5245 case L2CAP_INFO_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005246 err = l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005247 break;
5248
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005249 case L2CAP_CREATE_CHAN_REQ:
5250 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5251 break;
5252
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005253 case L2CAP_MOVE_CHAN_REQ:
5254 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5255 break;
5256
5257 case L2CAP_MOVE_CHAN_RSP:
5258 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
5259 break;
5260
5261 case L2CAP_MOVE_CHAN_CFM:
5262 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5263 break;
5264
5265 case L2CAP_MOVE_CHAN_CFM_RSP:
5266 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
5267 break;
5268
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005269 default:
5270 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5271 err = -EINVAL;
5272 break;
5273 }
5274
5275 return err;
5276}
5277
5278static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005279 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005280{
5281 switch (cmd->code) {
5282 case L2CAP_COMMAND_REJ:
5283 return 0;
5284
5285 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02005286 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005287
5288 case L2CAP_CONN_PARAM_UPDATE_RSP:
5289 return 0;
5290
5291 default:
5292 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5293 return -EINVAL;
5294 }
5295}
5296
Johan Hedberg7c2005d2013-09-16 13:05:16 +03005297static __le16 l2cap_err_to_reason(int err)
5298{
5299 switch (err) {
5300 case -EBADSLT:
5301 return __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
5302 case -EMSGSIZE:
5303 return __constant_cpu_to_le16(L2CAP_REJ_MTU_EXCEEDED);
5304 case -EINVAL:
5305 case -EPROTO:
5306 default:
5307 return __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
5308 }
5309}
5310
Johan Hedbergc5623552013-04-29 19:35:33 +03005311static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5312 struct sk_buff *skb)
5313{
5314 u8 *data = skb->data;
5315 int len = skb->len;
5316 struct l2cap_cmd_hdr cmd;
5317 int err;
5318
5319 l2cap_raw_recv(conn, skb);
5320
5321 while (len >= L2CAP_CMD_HDR_SIZE) {
5322 u16 cmd_len;
5323 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5324 data += L2CAP_CMD_HDR_SIZE;
5325 len -= L2CAP_CMD_HDR_SIZE;
5326
5327 cmd_len = le16_to_cpu(cmd.len);
5328
5329 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5330 cmd.ident);
5331
5332 if (cmd_len > len || !cmd.ident) {
5333 BT_DBG("corrupted command");
5334 break;
5335 }
5336
5337 err = l2cap_le_sig_cmd(conn, &cmd, data);
5338 if (err) {
5339 struct l2cap_cmd_rej_unk rej;
5340
5341 BT_ERR("Wrong link type (%d)", err);
5342
Johan Hedberg7c2005d2013-09-16 13:05:16 +03005343 rej.reason = l2cap_err_to_reason(err);
Johan Hedbergc5623552013-04-29 19:35:33 +03005344 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5345 sizeof(rej), &rej);
5346 }
5347
5348 data += cmd_len;
5349 len -= cmd_len;
5350 }
5351
5352 kfree_skb(skb);
5353}
5354
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005355static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005356 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005357{
5358 u8 *data = skb->data;
5359 int len = skb->len;
5360 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005361 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005362
5363 l2cap_raw_recv(conn, skb);
5364
5365 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005366 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005367 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5368 data += L2CAP_CMD_HDR_SIZE;
5369 len -= L2CAP_CMD_HDR_SIZE;
5370
Al Viro88219a02007-07-29 00:17:25 -07005371 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005372
Gustavo Padovan2d792812012-10-06 10:07:01 +01005373 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5374 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005375
Al Viro88219a02007-07-29 00:17:25 -07005376 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005377 BT_DBG("corrupted command");
5378 break;
5379 }
5380
Johan Hedbergc5623552013-04-29 19:35:33 +03005381 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005382 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005383 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005384
5385 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005386
Johan Hedberg7c2005d2013-09-16 13:05:16 +03005387 rej.reason = l2cap_err_to_reason(err);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005388 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5389 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005390 }
5391
Al Viro88219a02007-07-29 00:17:25 -07005392 data += cmd_len;
5393 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005394 }
5395
5396 kfree_skb(skb);
5397}
5398
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005399static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005400{
5401 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005402 int hdr_size;
5403
5404 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5405 hdr_size = L2CAP_EXT_HDR_SIZE;
5406 else
5407 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005408
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005409 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005410 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005411 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5412 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5413
5414 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005415 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005416 }
5417 return 0;
5418}
5419
Mat Martineau6ea00482012-05-17 20:53:52 -07005420static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005421{
Mat Martineaue31f7632012-05-17 20:53:41 -07005422 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005423
Mat Martineaue31f7632012-05-17 20:53:41 -07005424 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005425
Mat Martineaue31f7632012-05-17 20:53:41 -07005426 memset(&control, 0, sizeof(control));
5427 control.sframe = 1;
5428 control.final = 1;
5429 control.reqseq = chan->buffer_seq;
5430 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005431
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005432 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005433 control.super = L2CAP_SUPER_RNR;
5434 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005435 }
5436
Mat Martineaue31f7632012-05-17 20:53:41 -07005437 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5438 chan->unacked_frames > 0)
5439 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005440
Mat Martineaue31f7632012-05-17 20:53:41 -07005441 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005442 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005443
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005444 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005445 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5446 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5447 * send it now.
5448 */
5449 control.super = L2CAP_SUPER_RR;
5450 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005451 }
5452}
5453
Gustavo Padovan2d792812012-10-06 10:07:01 +01005454static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5455 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005456{
Mat Martineau84084a32011-07-22 14:54:00 -07005457 /* skb->len reflects data in skb as well as all fragments
5458 * skb->data_len reflects only data in fragments
5459 */
5460 if (!skb_has_frag_list(skb))
5461 skb_shinfo(skb)->frag_list = new_frag;
5462
5463 new_frag->next = NULL;
5464
5465 (*last_frag)->next = new_frag;
5466 *last_frag = new_frag;
5467
5468 skb->len += new_frag->len;
5469 skb->data_len += new_frag->len;
5470 skb->truesize += new_frag->truesize;
5471}
5472
Mat Martineau4b51dae92012-05-17 20:53:37 -07005473static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5474 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005475{
5476 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005477
Mat Martineau4b51dae92012-05-17 20:53:37 -07005478 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005479 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005480 if (chan->sdu)
5481 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005482
Gustavo Padovan80b98022012-05-27 22:27:51 -03005483 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005484 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005485
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005486 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005487 if (chan->sdu)
5488 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005489
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005490 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005491 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005492
Mat Martineau84084a32011-07-22 14:54:00 -07005493 if (chan->sdu_len > chan->imtu) {
5494 err = -EMSGSIZE;
5495 break;
5496 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005497
Mat Martineau84084a32011-07-22 14:54:00 -07005498 if (skb->len >= chan->sdu_len)
5499 break;
5500
5501 chan->sdu = skb;
5502 chan->sdu_last_frag = skb;
5503
5504 skb = NULL;
5505 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005506 break;
5507
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005508 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005509 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005510 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005511
Mat Martineau84084a32011-07-22 14:54:00 -07005512 append_skb_frag(chan->sdu, skb,
5513 &chan->sdu_last_frag);
5514 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005515
Mat Martineau84084a32011-07-22 14:54:00 -07005516 if (chan->sdu->len >= chan->sdu_len)
5517 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005518
Mat Martineau84084a32011-07-22 14:54:00 -07005519 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005520 break;
5521
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005522 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005523 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005524 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005525
Mat Martineau84084a32011-07-22 14:54:00 -07005526 append_skb_frag(chan->sdu, skb,
5527 &chan->sdu_last_frag);
5528 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005529
Mat Martineau84084a32011-07-22 14:54:00 -07005530 if (chan->sdu->len != chan->sdu_len)
5531 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005532
Gustavo Padovan80b98022012-05-27 22:27:51 -03005533 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005534
Mat Martineau84084a32011-07-22 14:54:00 -07005535 if (!err) {
5536 /* Reassembly complete */
5537 chan->sdu = NULL;
5538 chan->sdu_last_frag = NULL;
5539 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005540 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005541 break;
5542 }
5543
Mat Martineau84084a32011-07-22 14:54:00 -07005544 if (err) {
5545 kfree_skb(skb);
5546 kfree_skb(chan->sdu);
5547 chan->sdu = NULL;
5548 chan->sdu_last_frag = NULL;
5549 chan->sdu_len = 0;
5550 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005551
Mat Martineau84084a32011-07-22 14:54:00 -07005552 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005553}
5554
Mat Martineau32b32732012-10-23 15:24:11 -07005555static int l2cap_resegment(struct l2cap_chan *chan)
5556{
5557 /* Placeholder */
5558 return 0;
5559}
5560
Mat Martineaue3281402011-07-07 09:39:02 -07005561void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03005562{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005563 u8 event;
5564
5565 if (chan->mode != L2CAP_MODE_ERTM)
5566 return;
5567
5568 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005569 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005570}
5571
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005572static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5573{
Mat Martineau63838722012-05-17 20:53:45 -07005574 int err = 0;
5575 /* Pass sequential frames to l2cap_reassemble_sdu()
5576 * until a gap is encountered.
5577 */
5578
5579 BT_DBG("chan %p", chan);
5580
5581 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5582 struct sk_buff *skb;
5583 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5584 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5585
5586 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5587
5588 if (!skb)
5589 break;
5590
5591 skb_unlink(skb, &chan->srej_q);
5592 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5593 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5594 if (err)
5595 break;
5596 }
5597
5598 if (skb_queue_empty(&chan->srej_q)) {
5599 chan->rx_state = L2CAP_RX_STATE_RECV;
5600 l2cap_send_ack(chan);
5601 }
5602
5603 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005604}
5605
5606static void l2cap_handle_srej(struct l2cap_chan *chan,
5607 struct l2cap_ctrl *control)
5608{
Mat Martineauf80842a2012-05-17 20:53:46 -07005609 struct sk_buff *skb;
5610
5611 BT_DBG("chan %p, control %p", chan, control);
5612
5613 if (control->reqseq == chan->next_tx_seq) {
5614 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005615 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005616 return;
5617 }
5618
5619 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5620
5621 if (skb == NULL) {
5622 BT_DBG("Seq %d not available for retransmission",
5623 control->reqseq);
5624 return;
5625 }
5626
5627 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5628 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005629 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005630 return;
5631 }
5632
5633 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5634
5635 if (control->poll) {
5636 l2cap_pass_to_tx(chan, control);
5637
5638 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5639 l2cap_retransmit(chan, control);
5640 l2cap_ertm_send(chan);
5641
5642 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5643 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5644 chan->srej_save_reqseq = control->reqseq;
5645 }
5646 } else {
5647 l2cap_pass_to_tx_fbit(chan, control);
5648
5649 if (control->final) {
5650 if (chan->srej_save_reqseq != control->reqseq ||
5651 !test_and_clear_bit(CONN_SREJ_ACT,
5652 &chan->conn_state))
5653 l2cap_retransmit(chan, control);
5654 } else {
5655 l2cap_retransmit(chan, control);
5656 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5657 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5658 chan->srej_save_reqseq = control->reqseq;
5659 }
5660 }
5661 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005662}
5663
5664static void l2cap_handle_rej(struct l2cap_chan *chan,
5665 struct l2cap_ctrl *control)
5666{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005667 struct sk_buff *skb;
5668
5669 BT_DBG("chan %p, control %p", chan, control);
5670
5671 if (control->reqseq == chan->next_tx_seq) {
5672 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005673 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005674 return;
5675 }
5676
5677 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5678
5679 if (chan->max_tx && skb &&
5680 bt_cb(skb)->control.retries >= chan->max_tx) {
5681 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005682 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005683 return;
5684 }
5685
5686 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5687
5688 l2cap_pass_to_tx(chan, control);
5689
5690 if (control->final) {
5691 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5692 l2cap_retransmit_all(chan, control);
5693 } else {
5694 l2cap_retransmit_all(chan, control);
5695 l2cap_ertm_send(chan);
5696 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5697 set_bit(CONN_REJ_ACT, &chan->conn_state);
5698 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005699}
5700
Mat Martineau4b51dae92012-05-17 20:53:37 -07005701static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5702{
5703 BT_DBG("chan %p, txseq %d", chan, txseq);
5704
5705 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5706 chan->expected_tx_seq);
5707
5708 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5709 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005710 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005711 /* See notes below regarding "double poll" and
5712 * invalid packets.
5713 */
5714 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5715 BT_DBG("Invalid/Ignore - after SREJ");
5716 return L2CAP_TXSEQ_INVALID_IGNORE;
5717 } else {
5718 BT_DBG("Invalid - in window after SREJ sent");
5719 return L2CAP_TXSEQ_INVALID;
5720 }
5721 }
5722
5723 if (chan->srej_list.head == txseq) {
5724 BT_DBG("Expected SREJ");
5725 return L2CAP_TXSEQ_EXPECTED_SREJ;
5726 }
5727
5728 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5729 BT_DBG("Duplicate SREJ - txseq already stored");
5730 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5731 }
5732
5733 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5734 BT_DBG("Unexpected SREJ - not requested");
5735 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5736 }
5737 }
5738
5739 if (chan->expected_tx_seq == txseq) {
5740 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5741 chan->tx_win) {
5742 BT_DBG("Invalid - txseq outside tx window");
5743 return L2CAP_TXSEQ_INVALID;
5744 } else {
5745 BT_DBG("Expected");
5746 return L2CAP_TXSEQ_EXPECTED;
5747 }
5748 }
5749
5750 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01005751 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005752 BT_DBG("Duplicate - expected_tx_seq later than txseq");
5753 return L2CAP_TXSEQ_DUPLICATE;
5754 }
5755
5756 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
5757 /* A source of invalid packets is a "double poll" condition,
5758 * where delays cause us to send multiple poll packets. If
5759 * the remote stack receives and processes both polls,
5760 * sequence numbers can wrap around in such a way that a
5761 * resent frame has a sequence number that looks like new data
5762 * with a sequence gap. This would trigger an erroneous SREJ
5763 * request.
5764 *
5765 * Fortunately, this is impossible with a tx window that's
5766 * less than half of the maximum sequence number, which allows
5767 * invalid frames to be safely ignored.
5768 *
5769 * With tx window sizes greater than half of the tx window
5770 * maximum, the frame is invalid and cannot be ignored. This
5771 * causes a disconnect.
5772 */
5773
5774 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5775 BT_DBG("Invalid/Ignore - txseq outside tx window");
5776 return L2CAP_TXSEQ_INVALID_IGNORE;
5777 } else {
5778 BT_DBG("Invalid - txseq outside tx window");
5779 return L2CAP_TXSEQ_INVALID;
5780 }
5781 } else {
5782 BT_DBG("Unexpected - txseq indicates missing frames");
5783 return L2CAP_TXSEQ_UNEXPECTED;
5784 }
5785}
5786
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005787static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5788 struct l2cap_ctrl *control,
5789 struct sk_buff *skb, u8 event)
5790{
5791 int err = 0;
5792 bool skb_in_use = 0;
5793
5794 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5795 event);
5796
5797 switch (event) {
5798 case L2CAP_EV_RECV_IFRAME:
5799 switch (l2cap_classify_txseq(chan, control->txseq)) {
5800 case L2CAP_TXSEQ_EXPECTED:
5801 l2cap_pass_to_tx(chan, control);
5802
5803 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5804 BT_DBG("Busy, discarding expected seq %d",
5805 control->txseq);
5806 break;
5807 }
5808
5809 chan->expected_tx_seq = __next_seq(chan,
5810 control->txseq);
5811
5812 chan->buffer_seq = chan->expected_tx_seq;
5813 skb_in_use = 1;
5814
5815 err = l2cap_reassemble_sdu(chan, skb, control);
5816 if (err)
5817 break;
5818
5819 if (control->final) {
5820 if (!test_and_clear_bit(CONN_REJ_ACT,
5821 &chan->conn_state)) {
5822 control->final = 0;
5823 l2cap_retransmit_all(chan, control);
5824 l2cap_ertm_send(chan);
5825 }
5826 }
5827
5828 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5829 l2cap_send_ack(chan);
5830 break;
5831 case L2CAP_TXSEQ_UNEXPECTED:
5832 l2cap_pass_to_tx(chan, control);
5833
5834 /* Can't issue SREJ frames in the local busy state.
5835 * Drop this frame, it will be seen as missing
5836 * when local busy is exited.
5837 */
5838 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5839 BT_DBG("Busy, discarding unexpected seq %d",
5840 control->txseq);
5841 break;
5842 }
5843
5844 /* There was a gap in the sequence, so an SREJ
5845 * must be sent for each missing frame. The
5846 * current frame is stored for later use.
5847 */
5848 skb_queue_tail(&chan->srej_q, skb);
5849 skb_in_use = 1;
5850 BT_DBG("Queued %p (queue len %d)", skb,
5851 skb_queue_len(&chan->srej_q));
5852
5853 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5854 l2cap_seq_list_clear(&chan->srej_list);
5855 l2cap_send_srej(chan, control->txseq);
5856
5857 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5858 break;
5859 case L2CAP_TXSEQ_DUPLICATE:
5860 l2cap_pass_to_tx(chan, control);
5861 break;
5862 case L2CAP_TXSEQ_INVALID_IGNORE:
5863 break;
5864 case L2CAP_TXSEQ_INVALID:
5865 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005866 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005867 break;
5868 }
5869 break;
5870 case L2CAP_EV_RECV_RR:
5871 l2cap_pass_to_tx(chan, control);
5872 if (control->final) {
5873 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5874
Mat Martineaue6a3ee62012-10-23 15:24:22 -07005875 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
5876 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005877 control->final = 0;
5878 l2cap_retransmit_all(chan, control);
5879 }
5880
5881 l2cap_ertm_send(chan);
5882 } else if (control->poll) {
5883 l2cap_send_i_or_rr_or_rnr(chan);
5884 } else {
5885 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5886 &chan->conn_state) &&
5887 chan->unacked_frames)
5888 __set_retrans_timer(chan);
5889
5890 l2cap_ertm_send(chan);
5891 }
5892 break;
5893 case L2CAP_EV_RECV_RNR:
5894 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5895 l2cap_pass_to_tx(chan, control);
5896 if (control && control->poll) {
5897 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5898 l2cap_send_rr_or_rnr(chan, 0);
5899 }
5900 __clear_retrans_timer(chan);
5901 l2cap_seq_list_clear(&chan->retrans_list);
5902 break;
5903 case L2CAP_EV_RECV_REJ:
5904 l2cap_handle_rej(chan, control);
5905 break;
5906 case L2CAP_EV_RECV_SREJ:
5907 l2cap_handle_srej(chan, control);
5908 break;
5909 default:
5910 break;
5911 }
5912
5913 if (skb && !skb_in_use) {
5914 BT_DBG("Freeing %p", skb);
5915 kfree_skb(skb);
5916 }
5917
5918 return err;
5919}
5920
5921static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5922 struct l2cap_ctrl *control,
5923 struct sk_buff *skb, u8 event)
5924{
5925 int err = 0;
5926 u16 txseq = control->txseq;
5927 bool skb_in_use = 0;
5928
5929 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5930 event);
5931
5932 switch (event) {
5933 case L2CAP_EV_RECV_IFRAME:
5934 switch (l2cap_classify_txseq(chan, txseq)) {
5935 case L2CAP_TXSEQ_EXPECTED:
5936 /* Keep frame for reassembly later */
5937 l2cap_pass_to_tx(chan, control);
5938 skb_queue_tail(&chan->srej_q, skb);
5939 skb_in_use = 1;
5940 BT_DBG("Queued %p (queue len %d)", skb,
5941 skb_queue_len(&chan->srej_q));
5942
5943 chan->expected_tx_seq = __next_seq(chan, txseq);
5944 break;
5945 case L2CAP_TXSEQ_EXPECTED_SREJ:
5946 l2cap_seq_list_pop(&chan->srej_list);
5947
5948 l2cap_pass_to_tx(chan, control);
5949 skb_queue_tail(&chan->srej_q, skb);
5950 skb_in_use = 1;
5951 BT_DBG("Queued %p (queue len %d)", skb,
5952 skb_queue_len(&chan->srej_q));
5953
5954 err = l2cap_rx_queued_iframes(chan);
5955 if (err)
5956 break;
5957
5958 break;
5959 case L2CAP_TXSEQ_UNEXPECTED:
5960 /* Got a frame that can't be reassembled yet.
5961 * Save it for later, and send SREJs to cover
5962 * the missing frames.
5963 */
5964 skb_queue_tail(&chan->srej_q, skb);
5965 skb_in_use = 1;
5966 BT_DBG("Queued %p (queue len %d)", skb,
5967 skb_queue_len(&chan->srej_q));
5968
5969 l2cap_pass_to_tx(chan, control);
5970 l2cap_send_srej(chan, control->txseq);
5971 break;
5972 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
5973 /* This frame was requested with an SREJ, but
5974 * some expected retransmitted frames are
5975 * missing. Request retransmission of missing
5976 * SREJ'd frames.
5977 */
5978 skb_queue_tail(&chan->srej_q, skb);
5979 skb_in_use = 1;
5980 BT_DBG("Queued %p (queue len %d)", skb,
5981 skb_queue_len(&chan->srej_q));
5982
5983 l2cap_pass_to_tx(chan, control);
5984 l2cap_send_srej_list(chan, control->txseq);
5985 break;
5986 case L2CAP_TXSEQ_DUPLICATE_SREJ:
5987 /* We've already queued this frame. Drop this copy. */
5988 l2cap_pass_to_tx(chan, control);
5989 break;
5990 case L2CAP_TXSEQ_DUPLICATE:
5991 /* Expecting a later sequence number, so this frame
5992 * was already received. Ignore it completely.
5993 */
5994 break;
5995 case L2CAP_TXSEQ_INVALID_IGNORE:
5996 break;
5997 case L2CAP_TXSEQ_INVALID:
5998 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005999 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006000 break;
6001 }
6002 break;
6003 case L2CAP_EV_RECV_RR:
6004 l2cap_pass_to_tx(chan, control);
6005 if (control->final) {
6006 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6007
6008 if (!test_and_clear_bit(CONN_REJ_ACT,
6009 &chan->conn_state)) {
6010 control->final = 0;
6011 l2cap_retransmit_all(chan, control);
6012 }
6013
6014 l2cap_ertm_send(chan);
6015 } else if (control->poll) {
6016 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6017 &chan->conn_state) &&
6018 chan->unacked_frames) {
6019 __set_retrans_timer(chan);
6020 }
6021
6022 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6023 l2cap_send_srej_tail(chan);
6024 } else {
6025 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6026 &chan->conn_state) &&
6027 chan->unacked_frames)
6028 __set_retrans_timer(chan);
6029
6030 l2cap_send_ack(chan);
6031 }
6032 break;
6033 case L2CAP_EV_RECV_RNR:
6034 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6035 l2cap_pass_to_tx(chan, control);
6036 if (control->poll) {
6037 l2cap_send_srej_tail(chan);
6038 } else {
6039 struct l2cap_ctrl rr_control;
6040 memset(&rr_control, 0, sizeof(rr_control));
6041 rr_control.sframe = 1;
6042 rr_control.super = L2CAP_SUPER_RR;
6043 rr_control.reqseq = chan->buffer_seq;
6044 l2cap_send_sframe(chan, &rr_control);
6045 }
6046
6047 break;
6048 case L2CAP_EV_RECV_REJ:
6049 l2cap_handle_rej(chan, control);
6050 break;
6051 case L2CAP_EV_RECV_SREJ:
6052 l2cap_handle_srej(chan, control);
6053 break;
6054 }
6055
6056 if (skb && !skb_in_use) {
6057 BT_DBG("Freeing %p", skb);
6058 kfree_skb(skb);
6059 }
6060
6061 return err;
6062}
6063
Mat Martineau32b32732012-10-23 15:24:11 -07006064static int l2cap_finish_move(struct l2cap_chan *chan)
6065{
6066 BT_DBG("chan %p", chan);
6067
6068 chan->rx_state = L2CAP_RX_STATE_RECV;
6069
6070 if (chan->hs_hcon)
6071 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6072 else
6073 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6074
6075 return l2cap_resegment(chan);
6076}
6077
6078static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6079 struct l2cap_ctrl *control,
6080 struct sk_buff *skb, u8 event)
6081{
6082 int err;
6083
6084 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6085 event);
6086
6087 if (!control->poll)
6088 return -EPROTO;
6089
6090 l2cap_process_reqseq(chan, control->reqseq);
6091
6092 if (!skb_queue_empty(&chan->tx_q))
6093 chan->tx_send_head = skb_peek(&chan->tx_q);
6094 else
6095 chan->tx_send_head = NULL;
6096
6097 /* Rewind next_tx_seq to the point expected
6098 * by the receiver.
6099 */
6100 chan->next_tx_seq = control->reqseq;
6101 chan->unacked_frames = 0;
6102
6103 err = l2cap_finish_move(chan);
6104 if (err)
6105 return err;
6106
6107 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6108 l2cap_send_i_or_rr_or_rnr(chan);
6109
6110 if (event == L2CAP_EV_RECV_IFRAME)
6111 return -EPROTO;
6112
6113 return l2cap_rx_state_recv(chan, control, NULL, event);
6114}
6115
6116static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6117 struct l2cap_ctrl *control,
6118 struct sk_buff *skb, u8 event)
6119{
6120 int err;
6121
6122 if (!control->final)
6123 return -EPROTO;
6124
6125 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6126
6127 chan->rx_state = L2CAP_RX_STATE_RECV;
6128 l2cap_process_reqseq(chan, control->reqseq);
6129
6130 if (!skb_queue_empty(&chan->tx_q))
6131 chan->tx_send_head = skb_peek(&chan->tx_q);
6132 else
6133 chan->tx_send_head = NULL;
6134
6135 /* Rewind next_tx_seq to the point expected
6136 * by the receiver.
6137 */
6138 chan->next_tx_seq = control->reqseq;
6139 chan->unacked_frames = 0;
6140
6141 if (chan->hs_hcon)
6142 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6143 else
6144 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6145
6146 err = l2cap_resegment(chan);
6147
6148 if (!err)
6149 err = l2cap_rx_state_recv(chan, control, skb, event);
6150
6151 return err;
6152}
6153
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006154static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6155{
6156 /* Make sure reqseq is for a packet that has been sent but not acked */
6157 u16 unacked;
6158
6159 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6160 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6161}
6162
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006163static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6164 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006165{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006166 int err = 0;
6167
6168 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6169 control, skb, event, chan->rx_state);
6170
6171 if (__valid_reqseq(chan, control->reqseq)) {
6172 switch (chan->rx_state) {
6173 case L2CAP_RX_STATE_RECV:
6174 err = l2cap_rx_state_recv(chan, control, skb, event);
6175 break;
6176 case L2CAP_RX_STATE_SREJ_SENT:
6177 err = l2cap_rx_state_srej_sent(chan, control, skb,
6178 event);
6179 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006180 case L2CAP_RX_STATE_WAIT_P:
6181 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6182 break;
6183 case L2CAP_RX_STATE_WAIT_F:
6184 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6185 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006186 default:
6187 /* shut it down */
6188 break;
6189 }
6190 } else {
6191 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6192 control->reqseq, chan->next_tx_seq,
6193 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006194 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006195 }
6196
6197 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006198}
6199
6200static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6201 struct sk_buff *skb)
6202{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006203 int err = 0;
6204
6205 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6206 chan->rx_state);
6207
6208 if (l2cap_classify_txseq(chan, control->txseq) ==
6209 L2CAP_TXSEQ_EXPECTED) {
6210 l2cap_pass_to_tx(chan, control);
6211
6212 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6213 __next_seq(chan, chan->buffer_seq));
6214
6215 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6216
6217 l2cap_reassemble_sdu(chan, skb, control);
6218 } else {
6219 if (chan->sdu) {
6220 kfree_skb(chan->sdu);
6221 chan->sdu = NULL;
6222 }
6223 chan->sdu_last_frag = NULL;
6224 chan->sdu_len = 0;
6225
6226 if (skb) {
6227 BT_DBG("Freeing %p", skb);
6228 kfree_skb(skb);
6229 }
6230 }
6231
6232 chan->last_acked_seq = control->txseq;
6233 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6234
6235 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006236}
6237
6238static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6239{
6240 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6241 u16 len;
6242 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006243
Mat Martineaub76bbd62012-04-11 10:48:43 -07006244 __unpack_control(chan, skb);
6245
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006246 len = skb->len;
6247
6248 /*
6249 * We can just drop the corrupted I-frame here.
6250 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006251 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006252 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006253 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006254 goto drop;
6255
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006256 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006257 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006258
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006259 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006260 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006261
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006262 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006263 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006264 goto drop;
6265 }
6266
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006267 if (!control->sframe) {
6268 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006269
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006270 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6271 control->sar, control->reqseq, control->final,
6272 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006273
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006274 /* Validate F-bit - F=0 always valid, F=1 only
6275 * valid in TX WAIT_F
6276 */
6277 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006278 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006279
6280 if (chan->mode != L2CAP_MODE_STREAMING) {
6281 event = L2CAP_EV_RECV_IFRAME;
6282 err = l2cap_rx(chan, control, skb, event);
6283 } else {
6284 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006285 }
6286
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006287 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006288 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006289 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006290 const u8 rx_func_to_event[4] = {
6291 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6292 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6293 };
6294
6295 /* Only I-frames are expected in streaming mode */
6296 if (chan->mode == L2CAP_MODE_STREAMING)
6297 goto drop;
6298
6299 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6300 control->reqseq, control->final, control->poll,
6301 control->super);
6302
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006303 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006304 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006305 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006306 goto drop;
6307 }
6308
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006309 /* Validate F and P bits */
6310 if (control->final && (control->poll ||
6311 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6312 goto drop;
6313
6314 event = rx_func_to_event[control->super];
6315 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006316 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006317 }
6318
6319 return 0;
6320
6321drop:
6322 kfree_skb(skb);
6323 return 0;
6324}
6325
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006326static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6327 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006328{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006329 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006330
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006331 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006332 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006333 if (cid == L2CAP_CID_A2MP) {
6334 chan = a2mp_channel_create(conn, skb);
6335 if (!chan) {
6336 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006337 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006338 }
6339
6340 l2cap_chan_lock(chan);
6341 } else {
6342 BT_DBG("unknown cid 0x%4.4x", cid);
6343 /* Drop packet and return */
6344 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006345 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006346 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006347 }
6348
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006349 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006350
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006351 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006352 goto drop;
6353
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006354 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006355 case L2CAP_MODE_BASIC:
6356 /* If socket recv buffers overflows we drop data here
6357 * which is *bad* because L2CAP has to be reliable.
6358 * But we don't have any other choice. L2CAP doesn't
6359 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006360
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006361 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006362 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006363
Gustavo Padovan80b98022012-05-27 22:27:51 -03006364 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006365 goto done;
6366 break;
6367
6368 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006369 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006370 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006371 goto done;
6372
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006373 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006374 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006375 break;
6376 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006377
6378drop:
6379 kfree_skb(skb);
6380
6381done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006382 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006383}
6384
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006385static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6386 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006387{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006388 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006389
Ido Yarivc2287682012-04-20 15:46:07 -03006390 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006391 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006392 goto drop;
6393
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006394 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006395
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006396 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006397 goto drop;
6398
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006399 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006400 goto drop;
6401
Gustavo Padovan80b98022012-05-27 22:27:51 -03006402 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006403 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006404
6405drop:
6406 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006407}
6408
Marcel Holtmann72f78352013-04-23 00:59:00 -07006409static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006410 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006411{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006412 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006413
Johan Hedbergaf1c0132013-04-29 19:35:42 +03006414 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
Marcel Holtmann72f78352013-04-23 00:59:00 -07006415 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006416 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006417 goto drop;
6418
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006419 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006420
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006421 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006422 goto drop;
6423
Gustavo Padovan80b98022012-05-27 22:27:51 -03006424 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006425 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006426
6427drop:
6428 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006429}
6430
Linus Torvalds1da177e2005-04-16 15:20:36 -07006431static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6432{
6433 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006434 u16 cid, len;
6435 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006436
6437 skb_pull(skb, L2CAP_HDR_SIZE);
6438 cid = __le16_to_cpu(lh->cid);
6439 len = __le16_to_cpu(lh->len);
6440
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006441 if (len != skb->len) {
6442 kfree_skb(skb);
6443 return;
6444 }
6445
Linus Torvalds1da177e2005-04-16 15:20:36 -07006446 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6447
6448 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02006449 case L2CAP_CID_LE_SIGNALING:
Johan Hedbergc5623552013-04-29 19:35:33 +03006450 l2cap_le_sig_channel(conn, skb);
6451 break;
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006452 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006453 l2cap_sig_channel(conn, skb);
6454 break;
6455
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006456 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006457 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006458 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006459 l2cap_conless_channel(conn, psm, skb);
6460 break;
6461
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006462 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006463 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006464 break;
6465
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006466 case L2CAP_CID_SMP:
6467 if (smp_sig_channel(conn, skb))
6468 l2cap_conn_del(conn->hcon, EACCES);
6469 break;
6470
Linus Torvalds1da177e2005-04-16 15:20:36 -07006471 default:
6472 l2cap_data_channel(conn, cid, skb);
6473 break;
6474 }
6475}
6476
6477/* ---- L2CAP interface with lower layer (HCI) ---- */
6478
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006479int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006480{
6481 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006482 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006483
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006484 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006485
6486 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006487 read_lock(&chan_list_lock);
6488 list_for_each_entry(c, &chan_list, global_l) {
6489 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006490
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006491 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006492 continue;
6493
6494 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006495 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006496 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006497 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006498 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006499 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
6500 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006501 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006502 lm2 |= HCI_LM_MASTER;
6503 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006504 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006505 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006506
6507 return exact ? lm1 : lm2;
6508}
6509
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006510void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006511{
Marcel Holtmann01394182006-07-03 10:02:46 +02006512 struct l2cap_conn *conn;
6513
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006514 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006515
Linus Torvalds1da177e2005-04-16 15:20:36 -07006516 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03006517 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006518 if (conn)
6519 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006520 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006521 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006522 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006523}
6524
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006525int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006526{
6527 struct l2cap_conn *conn = hcon->l2cap_data;
6528
6529 BT_DBG("hcon %p", hcon);
6530
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006531 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006532 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006533 return conn->disc_reason;
6534}
6535
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006536void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006537{
6538 BT_DBG("hcon %p reason %d", hcon, reason);
6539
Joe Perchese1750722011-06-29 18:18:29 -07006540 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006541}
6542
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006543static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006544{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006545 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006546 return;
6547
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006548 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006549 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006550 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006551 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006552 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006553 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006554 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006555 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006556 }
6557}
6558
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006559int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006560{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006561 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006562 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006563
Marcel Holtmann01394182006-07-03 10:02:46 +02006564 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006565 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006566
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006567 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006568
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006569 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306570 if (!status && encrypt)
6571 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006572 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006573 }
6574
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006575 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006576
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006577 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006578 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006579
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006580 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6581 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006582
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006583 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6584 l2cap_chan_unlock(chan);
6585 continue;
6586 }
6587
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006588 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006589 if (!status && encrypt) {
6590 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006591 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006592 }
6593
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006594 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006595 continue;
6596 }
6597
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006598 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006599 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006600 continue;
6601 }
6602
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006603 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006604 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03006605 struct sock *sk = chan->sk;
6606
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006607 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03006608 sk->sk_state_change(sk);
6609
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006610 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006611 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006612 continue;
6613 }
6614
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006615 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006616 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006617 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006618 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006619 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006620 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006621 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006622 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006623 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006624 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006625
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006626 lock_sock(sk);
6627
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006628 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006629 if (test_bit(BT_SK_DEFER_SETUP,
6630 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006631 res = L2CAP_CR_PEND;
6632 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006633 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006634 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006635 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006636 res = L2CAP_CR_SUCCESS;
6637 stat = L2CAP_CS_NO_INFO;
6638 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006639 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006640 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006641 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006642 res = L2CAP_CR_SEC_BLOCK;
6643 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006644 }
6645
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006646 release_sock(sk);
6647
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006648 rsp.scid = cpu_to_le16(chan->dcid);
6649 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006650 rsp.result = cpu_to_le16(res);
6651 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006652 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006653 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006654
6655 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6656 res == L2CAP_CR_SUCCESS) {
6657 char buf[128];
6658 set_bit(CONF_REQ_SENT, &chan->conf_state);
6659 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6660 L2CAP_CONF_REQ,
6661 l2cap_build_conf_req(chan, buf),
6662 buf);
6663 chan->num_conf_req++;
6664 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006665 }
6666
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006667 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006668 }
6669
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006670 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006671
Linus Torvalds1da177e2005-04-16 15:20:36 -07006672 return 0;
6673}
6674
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006675int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006676{
6677 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006678 struct l2cap_hdr *hdr;
6679 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006680
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006681 /* For AMP controller do not create l2cap conn */
6682 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6683 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006684
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006685 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03006686 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006687
6688 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006689 goto drop;
6690
6691 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6692
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006693 switch (flags) {
6694 case ACL_START:
6695 case ACL_START_NO_FLUSH:
6696 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006697 if (conn->rx_len) {
6698 BT_ERR("Unexpected start frame (len %d)", skb->len);
6699 kfree_skb(conn->rx_skb);
6700 conn->rx_skb = NULL;
6701 conn->rx_len = 0;
6702 l2cap_conn_unreliable(conn, ECOMM);
6703 }
6704
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006705 /* Start fragment always begin with Basic L2CAP header */
6706 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006707 BT_ERR("Frame is too short (len %d)", skb->len);
6708 l2cap_conn_unreliable(conn, ECOMM);
6709 goto drop;
6710 }
6711
6712 hdr = (struct l2cap_hdr *) skb->data;
6713 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6714
6715 if (len == skb->len) {
6716 /* Complete frame received */
6717 l2cap_recv_frame(conn, skb);
6718 return 0;
6719 }
6720
6721 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6722
6723 if (skb->len > len) {
6724 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006725 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006726 l2cap_conn_unreliable(conn, ECOMM);
6727 goto drop;
6728 }
6729
6730 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006731 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006732 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006733 goto drop;
6734
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006735 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006736 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006737 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006738 break;
6739
6740 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006741 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6742
6743 if (!conn->rx_len) {
6744 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6745 l2cap_conn_unreliable(conn, ECOMM);
6746 goto drop;
6747 }
6748
6749 if (skb->len > conn->rx_len) {
6750 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006751 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006752 kfree_skb(conn->rx_skb);
6753 conn->rx_skb = NULL;
6754 conn->rx_len = 0;
6755 l2cap_conn_unreliable(conn, ECOMM);
6756 goto drop;
6757 }
6758
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006759 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006760 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006761 conn->rx_len -= skb->len;
6762
6763 if (!conn->rx_len) {
6764 /* Complete frame received */
6765 l2cap_recv_frame(conn, conn->rx_skb);
6766 conn->rx_skb = NULL;
6767 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006768 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006769 }
6770
6771drop:
6772 kfree_skb(skb);
6773 return 0;
6774}
6775
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006776static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006777{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006778 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006779
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006780 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006781
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006782 list_for_each_entry(c, &chan_list, global_l) {
6783 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006784
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006785 seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
6786 &bt_sk(sk)->src, &bt_sk(sk)->dst,
6787 c->state, __le16_to_cpu(c->psm),
6788 c->scid, c->dcid, c->imtu, c->omtu,
6789 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006790 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006791
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006792 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006793
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006794 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006795}
6796
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006797static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6798{
6799 return single_open(file, l2cap_debugfs_show, inode->i_private);
6800}
6801
6802static const struct file_operations l2cap_debugfs_fops = {
6803 .open = l2cap_debugfs_open,
6804 .read = seq_read,
6805 .llseek = seq_lseek,
6806 .release = single_release,
6807};
6808
6809static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006810
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006811int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006812{
6813 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006814
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006815 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006816 if (err < 0)
6817 return err;
6818
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006819 if (bt_debugfs) {
Gustavo Padovan2d792812012-10-06 10:07:01 +01006820 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6821 NULL, &l2cap_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006822 if (!l2cap_debugfs)
6823 BT_ERR("Failed to create L2CAP debug file");
6824 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006825
Linus Torvalds1da177e2005-04-16 15:20:36 -07006826 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006827}
6828
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006829void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006830{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006831 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006832 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006833}
6834
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006835module_param(disable_ertm, bool, 0644);
6836MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");