blob: 640423b4f411a6186d077cadfb969499dd27c42c [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
Gustavo F. Padovance5706b2010-07-13 11:57:11 -03004 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
Gustavo F. Padovan5d8868f2010-07-16 16:18:39 -03005 Copyright (C) 2010 Google Inc.
Gustavo F. Padovan590051d2011-12-18 13:39:33 -02006 Copyright (C) 2011 ProFUSION Embedded Systems
Mat Martineau422e9252012-04-27 16:50:55 -07007 Copyright (c) 2012 Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07008
9 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License version 2 as
13 published by the Free Software Foundation;
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
18 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090019 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090024 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
25 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070026 SOFTWARE IS DISCLAIMED.
27*/
28
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020029/* Bluetooth L2CAP core. */
Linus Torvalds1da177e2005-04-16 15:20:36 -070030
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/module.h>
32
Marcel Holtmannaef7d972010-03-21 05:27:45 +010033#include <linux/debugfs.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030034#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36#include <net/bluetooth/bluetooth.h>
37#include <net/bluetooth/hci_core.h>
38#include <net/bluetooth/l2cap.h>
Anderson Brigliab501d6a2011-06-07 18:46:31 -030039#include <net/bluetooth/smp.h>
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +030040#include <net/bluetooth/a2mp.h>
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +020041#include <net/bluetooth/amp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
Mat Martineaud1de6d42012-05-17 20:53:55 -070043bool disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020044
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070045static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Mat Martineau50a147c2011-11-02 16:18:34 -070046static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070047
Johannes Bergb5ad8b72011-06-01 08:54:45 +020048static LIST_HEAD(chan_list);
49static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
Linus Torvalds1da177e2005-04-16 15:20:36 -070051static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +010052 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030053static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
Gustavo Padovan2d792812012-10-06 10:07:01 +010054 void *data);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -030055static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +020056static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Gustavo Padovand6603662012-05-21 13:58:22 -030058static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
Gustavo Padovan2d792812012-10-06 10:07:01 +010059 struct sk_buff_head *skbs, u8 event);
Mat Martineau608bcc62012-05-17 20:53:32 -070060
Marcel Holtmann01394182006-07-03 10:02:46 +020061/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030062
Gustavo Padovan2d792812012-10-06 10:07:01 +010063static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
64 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020065{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020066 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030067
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020068 list_for_each_entry(c, &conn->chan_l, list) {
69 if (c->dcid == cid)
70 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020071 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020072 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020073}
74
Gustavo Padovan2d792812012-10-06 10:07:01 +010075static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
76 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020077{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020078 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030079
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020080 list_for_each_entry(c, &conn->chan_l, list) {
81 if (c->scid == cid)
82 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020083 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020084 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020085}
86
87/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -070088 * Returns locked channel. */
Gustavo Padovan2d792812012-10-06 10:07:01 +010089static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
90 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020091{
Gustavo F. Padovan48454072011-03-25 00:22:30 -030092 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030093
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020094 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030095 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -070096 if (c)
97 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020098 mutex_unlock(&conn->chan_lock);
99
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300100 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200101}
102
Mat Martineaub1a130b2012-10-23 15:24:09 -0700103/* Find channel with given DCID.
104 * Returns locked channel.
105 */
106static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
107 u16 cid)
108{
109 struct l2cap_chan *c;
110
111 mutex_lock(&conn->chan_lock);
112 c = __l2cap_get_chan_by_dcid(conn, cid);
113 if (c)
114 l2cap_chan_lock(c);
115 mutex_unlock(&conn->chan_lock);
116
117 return c;
118}
119
Gustavo Padovan2d792812012-10-06 10:07:01 +0100120static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
121 u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200122{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200123 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300124
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200125 list_for_each_entry(c, &conn->chan_l, list) {
126 if (c->ident == ident)
127 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200128 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200129 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200130}
131
Mat Martineau5b155ef2012-10-23 15:24:14 -0700132static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
133 u8 ident)
134{
135 struct l2cap_chan *c;
136
137 mutex_lock(&conn->chan_lock);
138 c = __l2cap_get_chan_by_ident(conn, ident);
139 if (c)
140 l2cap_chan_lock(c);
141 mutex_unlock(&conn->chan_lock);
142
143 return c;
144}
145
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300146static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300147{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300148 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300149
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300150 list_for_each_entry(c, &chan_list, global_l) {
151 if (c->sport == psm && !bacmp(&bt_sk(c->sk)->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100152 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300153 }
Szymon Janc250938c2011-11-16 09:32:22 +0100154 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300155}
156
157int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
158{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300159 int err;
160
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200161 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300162
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300163 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300164 err = -EADDRINUSE;
165 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300166 }
167
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300168 if (psm) {
169 chan->psm = psm;
170 chan->sport = psm;
171 err = 0;
172 } else {
173 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300174
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300175 err = -EINVAL;
176 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300177 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300178 chan->psm = cpu_to_le16(p);
179 chan->sport = cpu_to_le16(p);
180 err = 0;
181 break;
182 }
183 }
184
185done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200186 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300187 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300188}
189
190int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
191{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200192 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300193
194 chan->scid = scid;
195
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200196 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300197
198 return 0;
199}
200
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300201static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200202{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300203 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200204
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300205 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300206 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200207 return cid;
208 }
209
210 return 0;
211}
212
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200213static void __l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300214{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200215 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100216 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200217
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300218 chan->state = state;
Gustavo Padovan80b98022012-05-27 22:27:51 -0300219 chan->ops->state_change(chan, state);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300220}
221
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200222static void l2cap_state_change(struct l2cap_chan *chan, int state)
223{
224 struct sock *sk = chan->sk;
225
226 lock_sock(sk);
227 __l2cap_state_change(chan, state);
228 release_sock(sk);
229}
230
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200231static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err)
232{
233 struct sock *sk = chan->sk;
234
235 sk->sk_err = err;
236}
237
238static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
239{
240 struct sock *sk = chan->sk;
241
242 lock_sock(sk);
243 __l2cap_chan_set_err(chan, err);
244 release_sock(sk);
245}
246
Mat Martineau4239d162012-05-17 20:53:49 -0700247static void __set_retrans_timer(struct l2cap_chan *chan)
248{
249 if (!delayed_work_pending(&chan->monitor_timer) &&
250 chan->retrans_timeout) {
251 l2cap_set_timer(chan, &chan->retrans_timer,
252 msecs_to_jiffies(chan->retrans_timeout));
253 }
254}
255
256static void __set_monitor_timer(struct l2cap_chan *chan)
257{
258 __clear_retrans_timer(chan);
259 if (chan->monitor_timeout) {
260 l2cap_set_timer(chan, &chan->monitor_timer,
261 msecs_to_jiffies(chan->monitor_timeout));
262 }
263}
264
Mat Martineau608bcc62012-05-17 20:53:32 -0700265static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
266 u16 seq)
267{
268 struct sk_buff *skb;
269
270 skb_queue_walk(head, skb) {
271 if (bt_cb(skb)->control.txseq == seq)
272 return skb;
273 }
274
275 return NULL;
276}
277
Mat Martineau3c588192012-04-11 10:48:42 -0700278/* ---- L2CAP sequence number lists ---- */
279
280/* For ERTM, ordered lists of sequence numbers must be tracked for
281 * SREJ requests that are received and for frames that are to be
282 * retransmitted. These seq_list functions implement a singly-linked
283 * list in an array, where membership in the list can also be checked
284 * in constant time. Items can also be added to the tail of the list
285 * and removed from the head in constant time, without further memory
286 * allocs or frees.
287 */
288
289static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
290{
291 size_t alloc_size, i;
292
293 /* Allocated size is a power of 2 to map sequence numbers
294 * (which may be up to 14 bits) in to a smaller array that is
295 * sized for the negotiated ERTM transmit windows.
296 */
297 alloc_size = roundup_pow_of_two(size);
298
299 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
300 if (!seq_list->list)
301 return -ENOMEM;
302
303 seq_list->mask = alloc_size - 1;
304 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
305 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
306 for (i = 0; i < alloc_size; i++)
307 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
308
309 return 0;
310}
311
312static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
313{
314 kfree(seq_list->list);
315}
316
317static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
318 u16 seq)
319{
320 /* Constant-time check for list membership */
321 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
322}
323
324static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
325{
326 u16 mask = seq_list->mask;
327
328 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
329 /* In case someone tries to pop the head of an empty list */
330 return L2CAP_SEQ_LIST_CLEAR;
331 } else if (seq_list->head == seq) {
332 /* Head can be removed in constant time */
333 seq_list->head = seq_list->list[seq & mask];
334 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
335
336 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
337 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
338 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
339 }
340 } else {
341 /* Walk the list to find the sequence number */
342 u16 prev = seq_list->head;
343 while (seq_list->list[prev & mask] != seq) {
344 prev = seq_list->list[prev & mask];
345 if (prev == L2CAP_SEQ_LIST_TAIL)
346 return L2CAP_SEQ_LIST_CLEAR;
347 }
348
349 /* Unlink the number from the list and clear it */
350 seq_list->list[prev & mask] = seq_list->list[seq & mask];
351 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
352 if (seq_list->tail == seq)
353 seq_list->tail = prev;
354 }
355 return seq;
356}
357
358static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
359{
360 /* Remove the head in constant time */
361 return l2cap_seq_list_remove(seq_list, seq_list->head);
362}
363
364static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
365{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300366 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700367
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300368 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
369 return;
370
371 for (i = 0; i <= seq_list->mask; i++)
372 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
373
374 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
375 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700376}
377
378static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
379{
380 u16 mask = seq_list->mask;
381
382 /* All appends happen in constant time */
383
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300384 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
385 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700386
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300387 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
388 seq_list->head = seq;
389 else
390 seq_list->list[seq_list->tail & mask] = seq;
391
392 seq_list->tail = seq;
393 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700394}
395
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300396static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300397{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300398 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100399 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200400 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300401 int reason;
402
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200403 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300404
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200405 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200406 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300407
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300408 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300409 reason = ECONNREFUSED;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300410 else if (chan->state == BT_CONNECT &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100411 chan->sec_level != BT_SECURITY_SDP)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300412 reason = ECONNREFUSED;
413 else
414 reason = ETIMEDOUT;
415
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300416 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300417
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200418 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300419
Gustavo Padovan80b98022012-05-27 22:27:51 -0300420 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200421 mutex_unlock(&conn->chan_lock);
422
Ulisses Furquim371fd832011-12-21 20:02:36 -0200423 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300424}
425
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300426struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200427{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300428 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200429
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300430 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
431 if (!chan)
432 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200433
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200434 mutex_init(&chan->lock);
435
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200436 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300437 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200438 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300439
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300440 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300441
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300442 chan->state = BT_OPEN;
443
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530444 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300445
Mat Martineau28270112012-05-17 21:14:09 -0700446 /* This flag is cleared in l2cap_chan_ready() */
447 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
448
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300449 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100450
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300451 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200452}
453
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530454static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300455{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530456 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
457
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530458 BT_DBG("chan %p", chan);
459
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200460 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300461 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200462 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300463
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530464 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300465}
466
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530467void l2cap_chan_hold(struct l2cap_chan *c)
468{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530469 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530470
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530471 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530472}
473
474void l2cap_chan_put(struct l2cap_chan *c)
475{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530476 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530477
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530478 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530479}
480
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300481void l2cap_chan_set_defaults(struct l2cap_chan *chan)
482{
483 chan->fcs = L2CAP_FCS_CRC16;
484 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
485 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
486 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700487 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300488 chan->sec_level = BT_SECURITY_LOW;
489
490 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
491}
492
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300493void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200494{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300495 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200496 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200497
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200498 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100499
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300500 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200501
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200502 switch (chan->chan_type) {
503 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300504 if (conn->hcon->type == LE_LINK) {
505 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300506 chan->omtu = L2CAP_DEFAULT_MTU;
Johan Hedberg073d1cf2013-04-29 19:35:35 +0300507 chan->scid = L2CAP_CID_ATT;
508 chan->dcid = L2CAP_CID_ATT;
Ville Tervob62f3282011-02-10 22:38:50 -0300509 } else {
510 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300511 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300512 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300513 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200514 break;
515
516 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200517 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300518 chan->scid = L2CAP_CID_CONN_LESS;
519 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300520 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200521 break;
522
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300523 case L2CAP_CHAN_CONN_FIX_A2MP:
524 chan->scid = L2CAP_CID_A2MP;
525 chan->dcid = L2CAP_CID_A2MP;
526 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
527 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
528 break;
529
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200530 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200531 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300532 chan->scid = L2CAP_CID_SIGNALING;
533 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300534 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200535 }
536
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300537 chan->local_id = L2CAP_BESTEFFORT_ID;
538 chan->local_stype = L2CAP_SERV_BESTEFFORT;
539 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
540 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
541 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300542 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300543
Ulisses Furquim371fd832011-12-21 20:02:36 -0200544 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300545
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200546 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200547}
548
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300549void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200550{
551 mutex_lock(&conn->chan_lock);
552 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200553 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200554}
555
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300556void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200557{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300558 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200559
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300560 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200561
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300562 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200563
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900564 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300565 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300566 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200567 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200568
Ulisses Furquim371fd832011-12-21 20:02:36 -0200569 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300570
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300571 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300572
573 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
David Herrmann76a68ba2013-04-06 20:28:37 +0200574 hci_conn_drop(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300575
576 if (mgr && mgr->bredr_chan == chan)
577 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200578 }
579
Andrei Emeltchenko419e08c2012-10-31 15:46:34 +0200580 if (chan->hs_hchan) {
581 struct hci_chan *hs_hchan = chan->hs_hchan;
582
583 BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
584 amp_disconnect_logical_link(hs_hchan);
585 }
586
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100587 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200588
Mat Martineau28270112012-05-17 21:14:09 -0700589 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300590 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300591
Gustavo Padovanee556f62012-05-18 20:22:38 -0300592 switch(chan->mode) {
593 case L2CAP_MODE_BASIC:
594 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300595
Gustavo Padovanee556f62012-05-18 20:22:38 -0300596 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300597 __clear_retrans_timer(chan);
598 __clear_monitor_timer(chan);
599 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300600
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300601 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300602
Mat Martineau3c588192012-04-11 10:48:42 -0700603 l2cap_seq_list_free(&chan->srej_list);
604 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300605
606 /* fall through */
607
608 case L2CAP_MODE_STREAMING:
609 skb_queue_purge(&chan->tx_q);
610 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300611 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300612
613 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200614}
615
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300616void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300617{
618 struct l2cap_conn *conn = chan->conn;
619 struct sock *sk = chan->sk;
620
Gustavo Padovan2d792812012-10-06 10:07:01 +0100621 BT_DBG("chan %p state %s sk %p", chan, state_to_string(chan->state),
622 sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300623
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300624 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300625 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100626 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300627 break;
628
629 case BT_CONNECTED:
630 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300631 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100632 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300633 __set_chan_timer(chan, sk->sk_sndtimeo);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +0200634 l2cap_send_disconn_req(chan, reason);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300635 } else
636 l2cap_chan_del(chan, reason);
637 break;
638
639 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300640 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100641 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300642 struct l2cap_conn_rsp rsp;
643 __u16 result;
644
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300645 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300646 result = L2CAP_CR_SEC_BLOCK;
647 else
648 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300649 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300650
651 rsp.scid = cpu_to_le16(chan->dcid);
652 rsp.dcid = cpu_to_le16(chan->scid);
653 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300654 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300655 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100656 sizeof(rsp), &rsp);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300657 }
658
659 l2cap_chan_del(chan, reason);
660 break;
661
662 case BT_CONNECT:
663 case BT_DISCONN:
664 l2cap_chan_del(chan, reason);
665 break;
666
667 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100668 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300669 break;
670 }
671}
672
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300673static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530674{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300675 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300676 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530677 case BT_SECURITY_HIGH:
678 return HCI_AT_DEDICATED_BONDING_MITM;
679 case BT_SECURITY_MEDIUM:
680 return HCI_AT_DEDICATED_BONDING;
681 default:
682 return HCI_AT_NO_BONDING;
683 }
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +0300684 } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300685 if (chan->sec_level == BT_SECURITY_LOW)
686 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530687
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300688 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530689 return HCI_AT_NO_BONDING_MITM;
690 else
691 return HCI_AT_NO_BONDING;
692 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300693 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530694 case BT_SECURITY_HIGH:
695 return HCI_AT_GENERAL_BONDING_MITM;
696 case BT_SECURITY_MEDIUM:
697 return HCI_AT_GENERAL_BONDING;
698 default:
699 return HCI_AT_NO_BONDING;
700 }
701 }
702}
703
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200704/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200705int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200706{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300707 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100708 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200709
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300710 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100711
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300712 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200713}
714
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200715static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200716{
717 u8 id;
718
719 /* Get next available identificator.
720 * 1 - 128 are used by kernel.
721 * 129 - 199 are reserved.
722 * 200 - 254 are used by utilities like l2ping, etc.
723 */
724
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200725 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200726
727 if (++conn->tx_ident > 128)
728 conn->tx_ident = 1;
729
730 id = conn->tx_ident;
731
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200732 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200733
734 return id;
735}
736
Gustavo Padovan2d792812012-10-06 10:07:01 +0100737static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
738 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200739{
740 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200741 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200742
743 BT_DBG("code 0x%2.2x", code);
744
745 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300746 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200747
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200748 if (lmp_no_flush_capable(conn->hcon->hdev))
749 flags = ACL_START_NO_FLUSH;
750 else
751 flags = ACL_START;
752
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700753 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200754 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700755
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200756 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200757}
758
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700759static bool __chan_is_moving(struct l2cap_chan *chan)
760{
761 return chan->move_state != L2CAP_MOVE_STABLE &&
762 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
763}
764
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200765static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
766{
767 struct hci_conn *hcon = chan->conn->hcon;
768 u16 flags;
769
770 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100771 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200772
Mat Martineaud5f8a752012-10-23 15:24:18 -0700773 if (chan->hs_hcon && !__chan_is_moving(chan)) {
774 if (chan->hs_hchan)
775 hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
776 else
777 kfree_skb(skb);
778
779 return;
780 }
781
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200782 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100783 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200784 flags = ACL_START_NO_FLUSH;
785 else
786 flags = ACL_START;
787
788 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
789 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790}
791
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700792static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
793{
794 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
795 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
796
797 if (enh & L2CAP_CTRL_FRAME_TYPE) {
798 /* S-Frame */
799 control->sframe = 1;
800 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
801 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
802
803 control->sar = 0;
804 control->txseq = 0;
805 } else {
806 /* I-Frame */
807 control->sframe = 0;
808 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
809 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
810
811 control->poll = 0;
812 control->super = 0;
813 }
814}
815
816static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
817{
818 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
819 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
820
821 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
822 /* S-Frame */
823 control->sframe = 1;
824 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
825 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
826
827 control->sar = 0;
828 control->txseq = 0;
829 } else {
830 /* I-Frame */
831 control->sframe = 0;
832 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
833 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
834
835 control->poll = 0;
836 control->super = 0;
837 }
838}
839
840static inline void __unpack_control(struct l2cap_chan *chan,
841 struct sk_buff *skb)
842{
843 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
844 __unpack_extended_control(get_unaligned_le32(skb->data),
845 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700846 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700847 } else {
848 __unpack_enhanced_control(get_unaligned_le16(skb->data),
849 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700850 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700851 }
852}
853
854static u32 __pack_extended_control(struct l2cap_ctrl *control)
855{
856 u32 packed;
857
858 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
859 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
860
861 if (control->sframe) {
862 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
863 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
864 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
865 } else {
866 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
867 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
868 }
869
870 return packed;
871}
872
873static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
874{
875 u16 packed;
876
877 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
878 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
879
880 if (control->sframe) {
881 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
882 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
883 packed |= L2CAP_CTRL_FRAME_TYPE;
884 } else {
885 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
886 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
887 }
888
889 return packed;
890}
891
892static inline void __pack_control(struct l2cap_chan *chan,
893 struct l2cap_ctrl *control,
894 struct sk_buff *skb)
895{
896 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
897 put_unaligned_le32(__pack_extended_control(control),
898 skb->data + L2CAP_HDR_SIZE);
899 } else {
900 put_unaligned_le16(__pack_enhanced_control(control),
901 skb->data + L2CAP_HDR_SIZE);
902 }
903}
904
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300905static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
906{
907 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
908 return L2CAP_EXT_HDR_SIZE;
909 else
910 return L2CAP_ENH_HDR_SIZE;
911}
912
Mat Martineaua67d7f62012-05-17 20:53:35 -0700913static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
914 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300915{
916 struct sk_buff *skb;
917 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300918 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300919
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300920 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300921 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300922
Mat Martineaua67d7f62012-05-17 20:53:35 -0700923 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300924
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300925 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700926 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300927
928 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300929 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300930 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300931
Mat Martineaua67d7f62012-05-17 20:53:35 -0700932 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
933 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
934 else
935 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300936
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300937 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700938 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300939 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300940 }
941
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200942 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700943 return skb;
944}
945
946static void l2cap_send_sframe(struct l2cap_chan *chan,
947 struct l2cap_ctrl *control)
948{
949 struct sk_buff *skb;
950 u32 control_field;
951
952 BT_DBG("chan %p, control %p", chan, control);
953
954 if (!control->sframe)
955 return;
956
Mat Martineaub99e13a2012-10-23 15:24:19 -0700957 if (__chan_is_moving(chan))
958 return;
959
Mat Martineaua67d7f62012-05-17 20:53:35 -0700960 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
961 !control->poll)
962 control->final = 1;
963
964 if (control->super == L2CAP_SUPER_RR)
965 clear_bit(CONN_RNR_SENT, &chan->conn_state);
966 else if (control->super == L2CAP_SUPER_RNR)
967 set_bit(CONN_RNR_SENT, &chan->conn_state);
968
969 if (control->super != L2CAP_SUPER_SREJ) {
970 chan->last_acked_seq = control->reqseq;
971 __clear_ack_timer(chan);
972 }
973
974 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
975 control->final, control->poll, control->super);
976
977 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
978 control_field = __pack_extended_control(control);
979 else
980 control_field = __pack_enhanced_control(control);
981
982 skb = l2cap_create_sframe_pdu(chan, control_field);
983 if (!IS_ERR(skb))
984 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300985}
986
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700987static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300988{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700989 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300990
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700991 BT_DBG("chan %p, poll %d", chan, poll);
992
993 memset(&control, 0, sizeof(control));
994 control.sframe = 1;
995 control.poll = poll;
996
997 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
998 control.super = L2CAP_SUPER_RNR;
999 else
1000 control.super = L2CAP_SUPER_RR;
1001
1002 control.reqseq = chan->buffer_seq;
1003 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -03001004}
1005
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001006static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001007{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001008 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +03001009}
1010
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001011static bool __amp_capable(struct l2cap_chan *chan)
1012{
1013 struct l2cap_conn *conn = chan->conn;
1014
1015 if (enable_hs &&
Andrei Emeltchenko5d054162012-11-29 17:46:05 +02001016 hci_amp_capable() &&
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001017 chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED &&
1018 conn->fixed_chan_mask & L2CAP_FC_A2MP)
1019 return true;
1020 else
1021 return false;
1022}
1023
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02001024static bool l2cap_check_efs(struct l2cap_chan *chan)
1025{
1026 /* Check EFS parameters */
1027 return true;
1028}
1029
Andrei Emeltchenko2766be42012-09-27 17:26:21 +03001030void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001031{
1032 struct l2cap_conn *conn = chan->conn;
1033 struct l2cap_conn_req req;
1034
1035 req.scid = cpu_to_le16(chan->scid);
1036 req.psm = chan->psm;
1037
1038 chan->ident = l2cap_get_ident(conn);
1039
1040 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1041
1042 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1043}
1044
Mat Martineau8eb200b2012-10-23 15:24:17 -07001045static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id)
1046{
1047 struct l2cap_create_chan_req req;
1048 req.scid = cpu_to_le16(chan->scid);
1049 req.psm = chan->psm;
1050 req.amp_id = amp_id;
1051
1052 chan->ident = l2cap_get_ident(chan->conn);
1053
1054 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ,
1055 sizeof(req), &req);
1056}
1057
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001058static void l2cap_move_setup(struct l2cap_chan *chan)
1059{
1060 struct sk_buff *skb;
1061
1062 BT_DBG("chan %p", chan);
1063
1064 if (chan->mode != L2CAP_MODE_ERTM)
1065 return;
1066
1067 __clear_retrans_timer(chan);
1068 __clear_monitor_timer(chan);
1069 __clear_ack_timer(chan);
1070
1071 chan->retry_count = 0;
1072 skb_queue_walk(&chan->tx_q, skb) {
1073 if (bt_cb(skb)->control.retries)
1074 bt_cb(skb)->control.retries = 1;
1075 else
1076 break;
1077 }
1078
1079 chan->expected_tx_seq = chan->buffer_seq;
1080
1081 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1082 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1083 l2cap_seq_list_clear(&chan->retrans_list);
1084 l2cap_seq_list_clear(&chan->srej_list);
1085 skb_queue_purge(&chan->srej_q);
1086
1087 chan->tx_state = L2CAP_TX_STATE_XMIT;
1088 chan->rx_state = L2CAP_RX_STATE_MOVE;
1089
1090 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1091}
1092
Mat Martineau5f3847a2012-10-23 15:24:12 -07001093static void l2cap_move_done(struct l2cap_chan *chan)
1094{
1095 u8 move_role = chan->move_role;
1096 BT_DBG("chan %p", chan);
1097
1098 chan->move_state = L2CAP_MOVE_STABLE;
1099 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1100
1101 if (chan->mode != L2CAP_MODE_ERTM)
1102 return;
1103
1104 switch (move_role) {
1105 case L2CAP_MOVE_ROLE_INITIATOR:
1106 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1107 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1108 break;
1109 case L2CAP_MOVE_ROLE_RESPONDER:
1110 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1111 break;
1112 }
1113}
1114
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001115static void l2cap_chan_ready(struct l2cap_chan *chan)
1116{
Mat Martineau28270112012-05-17 21:14:09 -07001117 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001118 chan->conf_state = 0;
1119 __clear_chan_timer(chan);
1120
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001121 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001122
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001123 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001124}
1125
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001126static void l2cap_start_connection(struct l2cap_chan *chan)
1127{
1128 if (__amp_capable(chan)) {
1129 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1130 a2mp_discover_amp(chan);
1131 } else {
1132 l2cap_send_conn_req(chan);
1133 }
1134}
1135
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001136static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001137{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001138 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001139
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001140 if (conn->hcon->type == LE_LINK) {
1141 l2cap_chan_ready(chan);
1142 return;
1143 }
1144
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001145 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001146 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1147 return;
1148
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001149 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001150 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001151 l2cap_start_connection(chan);
1152 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001153 } else {
1154 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001155 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001156
1157 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1158 conn->info_ident = l2cap_get_ident(conn);
1159
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001160 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001161
Gustavo Padovan2d792812012-10-06 10:07:01 +01001162 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1163 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001164 }
1165}
1166
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001167static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1168{
1169 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001170 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001171 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1172
1173 switch (mode) {
1174 case L2CAP_MODE_ERTM:
1175 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1176 case L2CAP_MODE_STREAMING:
1177 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1178 default:
1179 return 0x00;
1180 }
1181}
1182
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001183static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001184{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001185 struct sock *sk = chan->sk;
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02001186 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001187 struct l2cap_disconn_req req;
1188
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001189 if (!conn)
1190 return;
1191
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001192 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001193 __clear_retrans_timer(chan);
1194 __clear_monitor_timer(chan);
1195 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001196 }
1197
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001198 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001199 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001200 return;
1201 }
1202
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001203 req.dcid = cpu_to_le16(chan->dcid);
1204 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001205 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1206 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001207
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001208 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001209 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001210 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001211 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001212}
1213
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001215static void l2cap_conn_start(struct l2cap_conn *conn)
1216{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001217 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001218
1219 BT_DBG("conn %p", conn);
1220
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001221 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001222
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001223 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001224 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001225
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001226 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001227
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001228 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001229 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001230 continue;
1231 }
1232
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001233 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001234 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001235 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001236 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001237 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001238 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001239
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001240 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001241 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001242 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001243 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001244 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001245 continue;
1246 }
1247
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001248 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001249
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001250 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001251 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001252 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001253 rsp.scid = cpu_to_le16(chan->dcid);
1254 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001255
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001256 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001257 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001258 if (test_bit(BT_SK_DEFER_SETUP,
1259 &bt_sk(sk)->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001260 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1261 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001262 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001263
1264 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001265 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001266 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1267 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001268 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001269 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001270 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001271 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1272 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001273 }
1274
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001275 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001276 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001277
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001278 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001279 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001280 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001281 continue;
1282 }
1283
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001284 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001285 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001286 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001287 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001288 }
1289
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001290 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001291 }
1292
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001293 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001294}
1295
Ido Yarivc2287682012-04-20 15:46:07 -03001296/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001297 * Returns closest match, locked.
1298 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001299static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001300 bdaddr_t *src,
1301 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001302{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001303 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001304
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001305 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001306
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001307 list_for_each_entry(c, &chan_list, global_l) {
1308 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001309
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001310 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001311 continue;
1312
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001313 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001314 int src_match, dst_match;
1315 int src_any, dst_any;
1316
Ville Tervob62f3282011-02-10 22:38:50 -03001317 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001318 src_match = !bacmp(&bt_sk(sk)->src, src);
1319 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1320 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001321 read_unlock(&chan_list_lock);
1322 return c;
1323 }
Ville Tervob62f3282011-02-10 22:38:50 -03001324
1325 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001326 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1327 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1328 if ((src_match && dst_any) || (src_any && dst_match) ||
1329 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001330 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001331 }
1332 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001333
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001334 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001335
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001336 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001337}
1338
1339static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1340{
Gustavo F. Padovanc916fbe2011-04-04 16:00:55 -03001341 struct sock *parent, *sk;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001342 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001343
1344 BT_DBG("");
1345
1346 /* Check if we have socket listening on cid */
Johan Hedberg073d1cf2013-04-29 19:35:35 +03001347 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
Ido Yarivc2287682012-04-20 15:46:07 -03001348 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001349 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001350 return;
1351
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001352 parent = pchan->sk;
1353
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001354 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001355
Gustavo Padovan80b98022012-05-27 22:27:51 -03001356 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001357 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001358 goto clean;
1359
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001360 sk = chan->sk;
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001361
Ville Tervob62f3282011-02-10 22:38:50 -03001362 hci_conn_hold(conn->hcon);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001363 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
Ville Tervob62f3282011-02-10 22:38:50 -03001364
Ville Tervob62f3282011-02-10 22:38:50 -03001365 bacpy(&bt_sk(sk)->src, conn->src);
1366 bacpy(&bt_sk(sk)->dst, conn->dst);
1367
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001368 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001369
Gustavo Padovan6754e0d2012-05-25 09:30:56 -03001370 l2cap_chan_ready(chan);
Ville Tervob62f3282011-02-10 22:38:50 -03001371
Ville Tervob62f3282011-02-10 22:38:50 -03001372clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001373 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001374}
1375
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001376static void l2cap_conn_ready(struct l2cap_conn *conn)
1377{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001378 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001379 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001380
1381 BT_DBG("conn %p", conn);
1382
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001383 if (!hcon->out && hcon->type == LE_LINK)
Ville Tervob62f3282011-02-10 22:38:50 -03001384 l2cap_le_conn_ready(conn);
1385
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001386 if (hcon->out && hcon->type == LE_LINK)
1387 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001388
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001389 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001390
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001391 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001392
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001393 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001394
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001395 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1396 l2cap_chan_unlock(chan);
1397 continue;
1398 }
1399
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001400 if (hcon->type == LE_LINK) {
1401 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001402 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001403
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001404 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001405 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001406 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001407 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001408 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001409 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001410 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001411
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001412 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001413 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001414
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001415 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001416 }
1417
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001418 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001419}
1420
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001421/* Notify sockets that we cannot guaranty reliability anymore */
1422static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1423{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001424 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001425
1426 BT_DBG("conn %p", conn);
1427
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001428 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001429
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001430 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001431 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001432 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001433 }
1434
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001435 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001436}
1437
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001438static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001439{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001440 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001441 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001442
Marcel Holtmann984947d2009-02-06 23:35:19 +01001443 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001444 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001445
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001446 l2cap_conn_start(conn);
1447}
1448
David Herrmann2c8e1412013-04-06 20:28:45 +02001449/*
1450 * l2cap_user
1451 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
1452 * callback is called during registration. The ->remove callback is called
1453 * during unregistration.
1454 * An l2cap_user object can either be explicitly unregistered or when the
1455 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
1456 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
1457 * External modules must own a reference to the l2cap_conn object if they intend
1458 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
1459 * any time if they don't.
1460 */
1461
1462int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
1463{
1464 struct hci_dev *hdev = conn->hcon->hdev;
1465 int ret;
1466
1467 /* We need to check whether l2cap_conn is registered. If it is not, we
1468 * must not register the l2cap_user. l2cap_conn_del() is unregisters
1469 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
1470 * relies on the parent hci_conn object to be locked. This itself relies
1471 * on the hci_dev object to be locked. So we must lock the hci device
1472 * here, too. */
1473
1474 hci_dev_lock(hdev);
1475
1476 if (user->list.next || user->list.prev) {
1477 ret = -EINVAL;
1478 goto out_unlock;
1479 }
1480
1481 /* conn->hchan is NULL after l2cap_conn_del() was called */
1482 if (!conn->hchan) {
1483 ret = -ENODEV;
1484 goto out_unlock;
1485 }
1486
1487 ret = user->probe(conn, user);
1488 if (ret)
1489 goto out_unlock;
1490
1491 list_add(&user->list, &conn->users);
1492 ret = 0;
1493
1494out_unlock:
1495 hci_dev_unlock(hdev);
1496 return ret;
1497}
1498EXPORT_SYMBOL(l2cap_register_user);
1499
1500void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
1501{
1502 struct hci_dev *hdev = conn->hcon->hdev;
1503
1504 hci_dev_lock(hdev);
1505
1506 if (!user->list.next || !user->list.prev)
1507 goto out_unlock;
1508
1509 list_del(&user->list);
1510 user->list.next = NULL;
1511 user->list.prev = NULL;
1512 user->remove(conn, user);
1513
1514out_unlock:
1515 hci_dev_unlock(hdev);
1516}
1517EXPORT_SYMBOL(l2cap_unregister_user);
1518
1519static void l2cap_unregister_all_users(struct l2cap_conn *conn)
1520{
1521 struct l2cap_user *user;
1522
1523 while (!list_empty(&conn->users)) {
1524 user = list_first_entry(&conn->users, struct l2cap_user, list);
1525 list_del(&user->list);
1526 user->list.next = NULL;
1527 user->list.prev = NULL;
1528 user->remove(conn, user);
1529 }
1530}
1531
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001532static void l2cap_conn_del(struct hci_conn *hcon, int err)
1533{
1534 struct l2cap_conn *conn = hcon->l2cap_data;
1535 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001536
1537 if (!conn)
1538 return;
1539
1540 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1541
1542 kfree_skb(conn->rx_skb);
1543
David Herrmann2c8e1412013-04-06 20:28:45 +02001544 l2cap_unregister_all_users(conn);
1545
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001546 mutex_lock(&conn->chan_lock);
1547
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001548 /* Kill channels */
1549 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001550 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001551 l2cap_chan_lock(chan);
1552
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001553 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001554
1555 l2cap_chan_unlock(chan);
1556
Gustavo Padovan80b98022012-05-27 22:27:51 -03001557 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001558 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001559 }
1560
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001561 mutex_unlock(&conn->chan_lock);
1562
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001563 hci_chan_del(conn->hchan);
1564
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001565 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001566 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001567
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001568 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001569 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001570 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001571 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001572
1573 hcon->l2cap_data = NULL;
David Herrmann9c903e32013-04-06 20:28:44 +02001574 conn->hchan = NULL;
1575 l2cap_conn_put(conn);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001576}
1577
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001578static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001579{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001580 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001581 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001582
Johan Hedbergd06cc412012-06-06 18:44:11 +08001583 BT_DBG("conn %p", conn);
1584
1585 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1586 smp_chan_destroy(conn);
1587 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1588 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001589}
1590
Claudio Takahasibaf43252013-04-11 13:55:50 -03001591static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592{
Marcel Holtmann01394182006-07-03 10:02:46 +02001593 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001594 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595
Claudio Takahasibaf43252013-04-11 13:55:50 -03001596 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597 return conn;
1598
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001599 hchan = hci_chan_create(hcon);
1600 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001603 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001604 if (!conn) {
1605 hci_chan_del(hchan);
1606 return NULL;
1607 }
1608
David Herrmann9c903e32013-04-06 20:28:44 +02001609 kref_init(&conn->ref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001610 hcon->l2cap_data = conn;
1611 conn->hcon = hcon;
David Herrmann9c903e32013-04-06 20:28:44 +02001612 hci_conn_get(conn->hcon);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001613 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001615 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001616
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001617 switch (hcon->type) {
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001618 case LE_LINK:
1619 if (hcon->hdev->le_mtu) {
1620 conn->mtu = hcon->hdev->le_mtu;
1621 break;
1622 }
1623 /* fall through */
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001624 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001625 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001626 break;
1627 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001628
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 conn->src = &hcon->hdev->bdaddr;
1630 conn->dst = &hcon->dst;
1631
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001632 conn->feat_mask = 0;
1633
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001635 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001636
1637 INIT_LIST_HEAD(&conn->chan_l);
David Herrmann2c8e1412013-04-06 20:28:45 +02001638 INIT_LIST_HEAD(&conn->users);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001640 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001641 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001642 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001643 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001644
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001645 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001646
Linus Torvalds1da177e2005-04-16 15:20:36 -07001647 return conn;
1648}
1649
David Herrmann9c903e32013-04-06 20:28:44 +02001650static void l2cap_conn_free(struct kref *ref)
1651{
1652 struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
1653
1654 hci_conn_put(conn->hcon);
1655 kfree(conn);
1656}
1657
1658void l2cap_conn_get(struct l2cap_conn *conn)
1659{
1660 kref_get(&conn->ref);
1661}
1662EXPORT_SYMBOL(l2cap_conn_get);
1663
1664void l2cap_conn_put(struct l2cap_conn *conn)
1665{
1666 kref_put(&conn->ref, l2cap_conn_free);
1667}
1668EXPORT_SYMBOL(l2cap_conn_put);
1669
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671
Ido Yarivc2287682012-04-20 15:46:07 -03001672/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673 * Returns closest match.
1674 */
Ido Yarivc2287682012-04-20 15:46:07 -03001675static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1676 bdaddr_t *src,
1677 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001679 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001681 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001682
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001683 list_for_each_entry(c, &chan_list, global_l) {
1684 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001685
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001686 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687 continue;
1688
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001689 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001690 int src_match, dst_match;
1691 int src_any, dst_any;
1692
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001694 src_match = !bacmp(&bt_sk(sk)->src, src);
1695 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1696 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001697 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001698 return c;
1699 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700
1701 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001702 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1703 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1704 if ((src_match && dst_any) || (src_any && dst_match) ||
1705 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001706 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 }
1708 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001710 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001711
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001712 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713}
1714
Andre Guedes8e9f9892012-04-24 21:02:55 -03001715int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1716 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001718 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 struct l2cap_conn *conn;
1721 struct hci_conn *hcon;
1722 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001723 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001724 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001726 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301727 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001728
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001729 hdev = hci_get_route(dst, src);
1730 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 return -EHOSTUNREACH;
1732
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001733 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001735 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001736
1737 /* PSM must be odd and lsb of upper byte must be 0 */
1738 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001739 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001740 err = -EINVAL;
1741 goto done;
1742 }
1743
1744 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1745 err = -EINVAL;
1746 goto done;
1747 }
1748
1749 switch (chan->mode) {
1750 case L2CAP_MODE_BASIC:
1751 break;
1752 case L2CAP_MODE_ERTM:
1753 case L2CAP_MODE_STREAMING:
1754 if (!disable_ertm)
1755 break;
1756 /* fall through */
1757 default:
1758 err = -ENOTSUPP;
1759 goto done;
1760 }
1761
Gustavo Padovan0797e012012-05-27 22:27:54 -03001762 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001763 case BT_CONNECT:
1764 case BT_CONNECT2:
1765 case BT_CONFIG:
1766 /* Already connecting */
1767 err = 0;
1768 goto done;
1769
1770 case BT_CONNECTED:
1771 /* Already connected */
1772 err = -EISCONN;
1773 goto done;
1774
1775 case BT_OPEN:
1776 case BT_BOUND:
1777 /* Can connect */
1778 break;
1779
1780 default:
1781 err = -EBADFD;
1782 goto done;
1783 }
1784
1785 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001786 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001787 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001788 release_sock(sk);
1789
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001790 chan->psm = psm;
1791 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001793 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001794
Johan Hedbergf224ca52013-04-29 19:35:36 +03001795 if (bdaddr_type_is_le(dst_type))
Andre Guedes8e9f9892012-04-24 21:02:55 -03001796 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001797 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001798 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001799 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001800 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001801
Ville Tervo30e76272011-02-22 16:10:53 -03001802 if (IS_ERR(hcon)) {
1803 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001805 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806
Claudio Takahasibaf43252013-04-11 13:55:50 -03001807 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 if (!conn) {
David Herrmann76a68ba2013-04-06 20:28:37 +02001809 hci_conn_drop(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001810 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811 goto done;
1812 }
1813
Johan Hedberg141d5702013-04-29 19:35:37 +03001814 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1815 hci_conn_drop(hcon);
1816 err = -EBUSY;
1817 goto done;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001818 }
1819
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820 /* Update source addr of the socket */
1821 bacpy(src, conn->src);
1822
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001823 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001824 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001825 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001826
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001827 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001828 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829
1830 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001831 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001832 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001833 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001834 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001835 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001836 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837 }
1838
Ville Tervo30e76272011-02-22 16:10:53 -03001839 err = 0;
1840
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001842 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001843 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844 hci_dev_put(hdev);
1845 return err;
1846}
1847
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001848int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001849{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001850 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001851 DECLARE_WAITQUEUE(wait, current);
1852 int err = 0;
1853 int timeo = HZ/5;
1854
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001855 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001856 set_current_state(TASK_INTERRUPTIBLE);
1857 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001858 if (!timeo)
1859 timeo = HZ/5;
1860
1861 if (signal_pending(current)) {
1862 err = sock_intr_errno(timeo);
1863 break;
1864 }
1865
1866 release_sock(sk);
1867 timeo = schedule_timeout(timeo);
1868 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001869 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001870
1871 err = sock_error(sk);
1872 if (err)
1873 break;
1874 }
1875 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001876 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001877 return err;
1878}
1879
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001880static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001881{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001882 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001883 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001884
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001885 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001886
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001887 l2cap_chan_lock(chan);
1888
Mat Martineau80909e02012-05-17 20:53:50 -07001889 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001890 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001891 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001892 return;
1893 }
1894
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001895 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001896
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001897 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001898 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001899}
1900
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001901static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001902{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001903 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001904 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001905
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001906 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001907
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001908 l2cap_chan_lock(chan);
1909
Mat Martineau80909e02012-05-17 20:53:50 -07001910 if (!chan->conn) {
1911 l2cap_chan_unlock(chan);
1912 l2cap_chan_put(chan);
1913 return;
1914 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001915
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001916 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001917 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001918 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001919}
1920
Gustavo Padovand6603662012-05-21 13:58:22 -03001921static void l2cap_streaming_send(struct l2cap_chan *chan,
1922 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001923{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001924 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001925 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001926
Mat Martineau37339372012-05-17 20:53:33 -07001927 BT_DBG("chan %p, skbs %p", chan, skbs);
1928
Mat Martineaub99e13a2012-10-23 15:24:19 -07001929 if (__chan_is_moving(chan))
1930 return;
1931
Mat Martineau37339372012-05-17 20:53:33 -07001932 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1933
1934 while (!skb_queue_empty(&chan->tx_q)) {
1935
1936 skb = skb_dequeue(&chan->tx_q);
1937
1938 bt_cb(skb)->control.retries = 1;
1939 control = &bt_cb(skb)->control;
1940
1941 control->reqseq = 0;
1942 control->txseq = chan->next_tx_seq;
1943
1944 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001945
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001946 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001947 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1948 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001949 }
1950
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001951 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001952
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001953 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001954
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001955 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001956 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001957 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001958}
1959
Szymon Janc67c9e842011-07-28 16:24:33 +02001960static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001961{
1962 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001963 struct l2cap_ctrl *control;
1964 int sent = 0;
1965
1966 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001967
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001968 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001969 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001970
Mat Martineau94122bb2012-05-02 09:42:02 -07001971 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1972 return 0;
1973
Mat Martineaub99e13a2012-10-23 15:24:19 -07001974 if (__chan_is_moving(chan))
1975 return 0;
1976
Mat Martineau18a48e72012-05-17 20:53:34 -07001977 while (chan->tx_send_head &&
1978 chan->unacked_frames < chan->remote_tx_win &&
1979 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001980
Mat Martineau18a48e72012-05-17 20:53:34 -07001981 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001982
Mat Martineau18a48e72012-05-17 20:53:34 -07001983 bt_cb(skb)->control.retries = 1;
1984 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001985
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001986 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001987 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001988
Mat Martineau18a48e72012-05-17 20:53:34 -07001989 control->reqseq = chan->buffer_seq;
1990 chan->last_acked_seq = chan->buffer_seq;
1991 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001992
Mat Martineau18a48e72012-05-17 20:53:34 -07001993 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001994
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001995 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001996 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1997 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001998 }
1999
Mat Martineau18a48e72012-05-17 20:53:34 -07002000 /* Clone after data has been modified. Data is assumed to be
2001 read-only (for locking purposes) on cloned sk_buffs.
2002 */
2003 tx_skb = skb_clone(skb, GFP_KERNEL);
2004
2005 if (!tx_skb)
2006 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03002007
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03002008 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002009
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002010 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07002011 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002012 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07002013 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002014
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002015 if (skb_queue_is_last(&chan->tx_q, skb))
2016 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002017 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03002018 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07002019
2020 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002021 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002022 }
2023
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002024 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2025 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07002026
2027 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03002028}
2029
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002030static void l2cap_ertm_resend(struct l2cap_chan *chan)
2031{
2032 struct l2cap_ctrl control;
2033 struct sk_buff *skb;
2034 struct sk_buff *tx_skb;
2035 u16 seq;
2036
2037 BT_DBG("chan %p", chan);
2038
2039 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2040 return;
2041
Mat Martineaub99e13a2012-10-23 15:24:19 -07002042 if (__chan_is_moving(chan))
2043 return;
2044
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002045 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2046 seq = l2cap_seq_list_pop(&chan->retrans_list);
2047
2048 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2049 if (!skb) {
2050 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01002051 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002052 continue;
2053 }
2054
2055 bt_cb(skb)->control.retries++;
2056 control = bt_cb(skb)->control;
2057
2058 if (chan->max_tx != 0 &&
2059 bt_cb(skb)->control.retries > chan->max_tx) {
2060 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002061 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002062 l2cap_seq_list_clear(&chan->retrans_list);
2063 break;
2064 }
2065
2066 control.reqseq = chan->buffer_seq;
2067 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2068 control.final = 1;
2069 else
2070 control.final = 0;
2071
2072 if (skb_cloned(skb)) {
2073 /* Cloned sk_buffs are read-only, so we need a
2074 * writeable copy
2075 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002076 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002077 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002078 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002079 }
2080
2081 if (!tx_skb) {
2082 l2cap_seq_list_clear(&chan->retrans_list);
2083 break;
2084 }
2085
2086 /* Update skb contents */
2087 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2088 put_unaligned_le32(__pack_extended_control(&control),
2089 tx_skb->data + L2CAP_HDR_SIZE);
2090 } else {
2091 put_unaligned_le16(__pack_enhanced_control(&control),
2092 tx_skb->data + L2CAP_HDR_SIZE);
2093 }
2094
2095 if (chan->fcs == L2CAP_FCS_CRC16) {
2096 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
2097 put_unaligned_le16(fcs, skb_put(tx_skb,
2098 L2CAP_FCS_SIZE));
2099 }
2100
2101 l2cap_do_send(chan, tx_skb);
2102
2103 BT_DBG("Resent txseq %d", control.txseq);
2104
2105 chan->last_acked_seq = chan->buffer_seq;
2106 }
2107}
2108
Mat Martineauf80842a2012-05-17 20:53:46 -07002109static void l2cap_retransmit(struct l2cap_chan *chan,
2110 struct l2cap_ctrl *control)
2111{
2112 BT_DBG("chan %p, control %p", chan, control);
2113
2114 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2115 l2cap_ertm_resend(chan);
2116}
2117
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002118static void l2cap_retransmit_all(struct l2cap_chan *chan,
2119 struct l2cap_ctrl *control)
2120{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002121 struct sk_buff *skb;
2122
2123 BT_DBG("chan %p, control %p", chan, control);
2124
2125 if (control->poll)
2126 set_bit(CONN_SEND_FBIT, &chan->conn_state);
2127
2128 l2cap_seq_list_clear(&chan->retrans_list);
2129
2130 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2131 return;
2132
2133 if (chan->unacked_frames) {
2134 skb_queue_walk(&chan->tx_q, skb) {
2135 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002136 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07002137 break;
2138 }
2139
2140 skb_queue_walk_from(&chan->tx_q, skb) {
2141 if (skb == chan->tx_send_head)
2142 break;
2143
2144 l2cap_seq_list_append(&chan->retrans_list,
2145 bt_cb(skb)->control.txseq);
2146 }
2147
2148 l2cap_ertm_resend(chan);
2149 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002150}
2151
Szymon Jancb17e73b2012-01-11 10:59:47 +01002152static void l2cap_send_ack(struct l2cap_chan *chan)
2153{
Mat Martineau0a0aba42012-05-17 20:53:39 -07002154 struct l2cap_ctrl control;
2155 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2156 chan->last_acked_seq);
2157 int threshold;
2158
2159 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2160 chan, chan->last_acked_seq, chan->buffer_seq);
2161
2162 memset(&control, 0, sizeof(control));
2163 control.sframe = 1;
2164
2165 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2166 chan->rx_state == L2CAP_RX_STATE_RECV) {
2167 __clear_ack_timer(chan);
2168 control.super = L2CAP_SUPER_RNR;
2169 control.reqseq = chan->buffer_seq;
2170 l2cap_send_sframe(chan, &control);
2171 } else {
2172 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2173 l2cap_ertm_send(chan);
2174 /* If any i-frames were sent, they included an ack */
2175 if (chan->buffer_seq == chan->last_acked_seq)
2176 frames_to_ack = 0;
2177 }
2178
Mat Martineauc20f8e32012-07-10 05:47:07 -07002179 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002180 * Calculate without mul or div
2181 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002182 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002183 threshold += threshold << 1;
2184 threshold >>= 2;
2185
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002186 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002187 threshold);
2188
2189 if (frames_to_ack >= threshold) {
2190 __clear_ack_timer(chan);
2191 control.super = L2CAP_SUPER_RR;
2192 control.reqseq = chan->buffer_seq;
2193 l2cap_send_sframe(chan, &control);
2194 frames_to_ack = 0;
2195 }
2196
2197 if (frames_to_ack)
2198 __set_ack_timer(chan);
2199 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002200}
2201
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002202static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2203 struct msghdr *msg, int len,
2204 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002205{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002206 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002207 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002208 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002209
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002210 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002211 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002212
2213 sent += count;
2214 len -= count;
2215
2216 /* Continuation fragments (no L2CAP header) */
2217 frag = &skb_shinfo(skb)->frag_list;
2218 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002219 struct sk_buff *tmp;
2220
Linus Torvalds1da177e2005-04-16 15:20:36 -07002221 count = min_t(unsigned int, conn->mtu, len);
2222
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002223 tmp = chan->ops->alloc_skb(chan, count,
2224 msg->msg_flags & MSG_DONTWAIT);
2225 if (IS_ERR(tmp))
2226 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002227
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002228 *frag = tmp;
2229
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002230 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2231 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002232
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002233 (*frag)->priority = skb->priority;
2234
Linus Torvalds1da177e2005-04-16 15:20:36 -07002235 sent += count;
2236 len -= count;
2237
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002238 skb->len += (*frag)->len;
2239 skb->data_len += (*frag)->len;
2240
Linus Torvalds1da177e2005-04-16 15:20:36 -07002241 frag = &(*frag)->next;
2242 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002243
2244 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002245}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002246
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002247static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002248 struct msghdr *msg, size_t len,
2249 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002250{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002251 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002252 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002253 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002254 struct l2cap_hdr *lh;
2255
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002256 BT_DBG("chan %p len %zu priority %u", chan, len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002257
2258 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002259
2260 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002261 msg->msg_flags & MSG_DONTWAIT);
2262 if (IS_ERR(skb))
2263 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002264
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002265 skb->priority = priority;
2266
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002267 /* Create L2CAP header */
2268 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002269 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002270 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
2271 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002272
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002273 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002274 if (unlikely(err < 0)) {
2275 kfree_skb(skb);
2276 return ERR_PTR(err);
2277 }
2278 return skb;
2279}
2280
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002281static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002282 struct msghdr *msg, size_t len,
2283 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002284{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002285 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002286 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002287 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002288 struct l2cap_hdr *lh;
2289
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002290 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002291
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002292 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002293
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002294 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002295 msg->msg_flags & MSG_DONTWAIT);
2296 if (IS_ERR(skb))
2297 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002298
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002299 skb->priority = priority;
2300
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002301 /* Create L2CAP header */
2302 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002303 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002304 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002305
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002306 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002307 if (unlikely(err < 0)) {
2308 kfree_skb(skb);
2309 return ERR_PTR(err);
2310 }
2311 return skb;
2312}
2313
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002314static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002315 struct msghdr *msg, size_t len,
2316 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002317{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002318 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002319 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002320 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002321 struct l2cap_hdr *lh;
2322
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002323 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002324
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002325 if (!conn)
2326 return ERR_PTR(-ENOTCONN);
2327
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002328 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002329
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002330 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002331 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002332
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002333 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002334 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002335
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002336 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002337
2338 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002339 msg->msg_flags & MSG_DONTWAIT);
2340 if (IS_ERR(skb))
2341 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002342
2343 /* Create L2CAP header */
2344 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002345 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002346 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002347
Mat Martineau18a48e72012-05-17 20:53:34 -07002348 /* Control header is populated later */
2349 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2350 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2351 else
2352 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002353
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002354 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002355 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002356
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002357 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002358 if (unlikely(err < 0)) {
2359 kfree_skb(skb);
2360 return ERR_PTR(err);
2361 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002362
Mat Martineau18a48e72012-05-17 20:53:34 -07002363 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002364 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002365 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002366}
2367
Mat Martineau94122bb2012-05-02 09:42:02 -07002368static int l2cap_segment_sdu(struct l2cap_chan *chan,
2369 struct sk_buff_head *seg_queue,
2370 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002371{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002372 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002373 u16 sdu_len;
2374 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002375 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002376
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002377 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002378
Mat Martineau94122bb2012-05-02 09:42:02 -07002379 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2380 * so fragmented skbs are not used. The HCI layer's handling
2381 * of fragmented skbs is not compatible with ERTM's queueing.
2382 */
2383
2384 /* PDU size is derived from the HCI MTU */
2385 pdu_len = chan->conn->mtu;
2386
Mat Martineaua5495742012-10-23 15:24:21 -07002387 /* Constrain PDU size for BR/EDR connections */
2388 if (!chan->hs_hcon)
2389 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
Mat Martineau94122bb2012-05-02 09:42:02 -07002390
2391 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002392 if (chan->fcs)
2393 pdu_len -= L2CAP_FCS_SIZE;
2394
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002395 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002396
2397 /* Remote device may have requested smaller PDUs */
2398 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2399
2400 if (len <= pdu_len) {
2401 sar = L2CAP_SAR_UNSEGMENTED;
2402 sdu_len = 0;
2403 pdu_len = len;
2404 } else {
2405 sar = L2CAP_SAR_START;
2406 sdu_len = len;
2407 pdu_len -= L2CAP_SDULEN_SIZE;
2408 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002409
2410 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002411 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002412
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002413 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002414 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002415 return PTR_ERR(skb);
2416 }
2417
Mat Martineau94122bb2012-05-02 09:42:02 -07002418 bt_cb(skb)->control.sar = sar;
2419 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002420
Mat Martineau94122bb2012-05-02 09:42:02 -07002421 len -= pdu_len;
2422 if (sdu_len) {
2423 sdu_len = 0;
2424 pdu_len += L2CAP_SDULEN_SIZE;
2425 }
2426
2427 if (len <= pdu_len) {
2428 sar = L2CAP_SAR_END;
2429 pdu_len = len;
2430 } else {
2431 sar = L2CAP_SAR_CONTINUE;
2432 }
2433 }
2434
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002435 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002436}
2437
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002438int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002439 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002440{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002441 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002442 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002443 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002444
2445 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002446 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002447 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002448 if (IS_ERR(skb))
2449 return PTR_ERR(skb);
2450
2451 l2cap_do_send(chan, skb);
2452 return len;
2453 }
2454
2455 switch (chan->mode) {
2456 case L2CAP_MODE_BASIC:
2457 /* Check outgoing MTU */
2458 if (len > chan->omtu)
2459 return -EMSGSIZE;
2460
2461 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002462 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002463 if (IS_ERR(skb))
2464 return PTR_ERR(skb);
2465
2466 l2cap_do_send(chan, skb);
2467 err = len;
2468 break;
2469
2470 case L2CAP_MODE_ERTM:
2471 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002472 /* Check outgoing MTU */
2473 if (len > chan->omtu) {
2474 err = -EMSGSIZE;
2475 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002476 }
2477
Mat Martineau94122bb2012-05-02 09:42:02 -07002478 __skb_queue_head_init(&seg_queue);
2479
2480 /* Do segmentation before calling in to the state machine,
2481 * since it's possible to block while waiting for memory
2482 * allocation.
2483 */
2484 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2485
2486 /* The channel could have been closed while segmenting,
2487 * check that it is still connected.
2488 */
2489 if (chan->state != BT_CONNECTED) {
2490 __skb_queue_purge(&seg_queue);
2491 err = -ENOTCONN;
2492 }
2493
2494 if (err)
2495 break;
2496
Mat Martineau37339372012-05-17 20:53:33 -07002497 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002498 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002499 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002500 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002501
Gustavo Padovand6603662012-05-21 13:58:22 -03002502 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002503
Mat Martineau94122bb2012-05-02 09:42:02 -07002504 /* If the skbs were not queued for sending, they'll still be in
2505 * seg_queue and need to be purged.
2506 */
2507 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002508 break;
2509
2510 default:
2511 BT_DBG("bad state %1.1x", chan->mode);
2512 err = -EBADFD;
2513 }
2514
2515 return err;
2516}
2517
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002518static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2519{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002520 struct l2cap_ctrl control;
2521 u16 seq;
2522
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002523 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002524
2525 memset(&control, 0, sizeof(control));
2526 control.sframe = 1;
2527 control.super = L2CAP_SUPER_SREJ;
2528
2529 for (seq = chan->expected_tx_seq; seq != txseq;
2530 seq = __next_seq(chan, seq)) {
2531 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2532 control.reqseq = seq;
2533 l2cap_send_sframe(chan, &control);
2534 l2cap_seq_list_append(&chan->srej_list, seq);
2535 }
2536 }
2537
2538 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002539}
2540
2541static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2542{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002543 struct l2cap_ctrl control;
2544
2545 BT_DBG("chan %p", chan);
2546
2547 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2548 return;
2549
2550 memset(&control, 0, sizeof(control));
2551 control.sframe = 1;
2552 control.super = L2CAP_SUPER_SREJ;
2553 control.reqseq = chan->srej_list.tail;
2554 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002555}
2556
2557static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2558{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002559 struct l2cap_ctrl control;
2560 u16 initial_head;
2561 u16 seq;
2562
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002563 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002564
2565 memset(&control, 0, sizeof(control));
2566 control.sframe = 1;
2567 control.super = L2CAP_SUPER_SREJ;
2568
2569 /* Capture initial list head to allow only one pass through the list. */
2570 initial_head = chan->srej_list.head;
2571
2572 do {
2573 seq = l2cap_seq_list_pop(&chan->srej_list);
2574 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2575 break;
2576
2577 control.reqseq = seq;
2578 l2cap_send_sframe(chan, &control);
2579 l2cap_seq_list_append(&chan->srej_list, seq);
2580 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002581}
2582
Mat Martineau608bcc62012-05-17 20:53:32 -07002583static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2584{
2585 struct sk_buff *acked_skb;
2586 u16 ackseq;
2587
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002588 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002589
2590 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2591 return;
2592
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002593 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002594 chan->expected_ack_seq, chan->unacked_frames);
2595
2596 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2597 ackseq = __next_seq(chan, ackseq)) {
2598
2599 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2600 if (acked_skb) {
2601 skb_unlink(acked_skb, &chan->tx_q);
2602 kfree_skb(acked_skb);
2603 chan->unacked_frames--;
2604 }
2605 }
2606
2607 chan->expected_ack_seq = reqseq;
2608
2609 if (chan->unacked_frames == 0)
2610 __clear_retrans_timer(chan);
2611
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002612 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002613}
2614
2615static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2616{
2617 BT_DBG("chan %p", chan);
2618
2619 chan->expected_tx_seq = chan->buffer_seq;
2620 l2cap_seq_list_clear(&chan->srej_list);
2621 skb_queue_purge(&chan->srej_q);
2622 chan->rx_state = L2CAP_RX_STATE_RECV;
2623}
2624
Gustavo Padovand6603662012-05-21 13:58:22 -03002625static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2626 struct l2cap_ctrl *control,
2627 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002628{
Mat Martineau608bcc62012-05-17 20:53:32 -07002629 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2630 event);
2631
2632 switch (event) {
2633 case L2CAP_EV_DATA_REQUEST:
2634 if (chan->tx_send_head == NULL)
2635 chan->tx_send_head = skb_peek(skbs);
2636
2637 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2638 l2cap_ertm_send(chan);
2639 break;
2640 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2641 BT_DBG("Enter LOCAL_BUSY");
2642 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2643
2644 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2645 /* The SREJ_SENT state must be aborted if we are to
2646 * enter the LOCAL_BUSY state.
2647 */
2648 l2cap_abort_rx_srej_sent(chan);
2649 }
2650
2651 l2cap_send_ack(chan);
2652
2653 break;
2654 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2655 BT_DBG("Exit LOCAL_BUSY");
2656 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2657
2658 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2659 struct l2cap_ctrl local_control;
2660
2661 memset(&local_control, 0, sizeof(local_control));
2662 local_control.sframe = 1;
2663 local_control.super = L2CAP_SUPER_RR;
2664 local_control.poll = 1;
2665 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002666 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002667
2668 chan->retry_count = 1;
2669 __set_monitor_timer(chan);
2670 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2671 }
2672 break;
2673 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2674 l2cap_process_reqseq(chan, control->reqseq);
2675 break;
2676 case L2CAP_EV_EXPLICIT_POLL:
2677 l2cap_send_rr_or_rnr(chan, 1);
2678 chan->retry_count = 1;
2679 __set_monitor_timer(chan);
2680 __clear_ack_timer(chan);
2681 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2682 break;
2683 case L2CAP_EV_RETRANS_TO:
2684 l2cap_send_rr_or_rnr(chan, 1);
2685 chan->retry_count = 1;
2686 __set_monitor_timer(chan);
2687 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2688 break;
2689 case L2CAP_EV_RECV_FBIT:
2690 /* Nothing to process */
2691 break;
2692 default:
2693 break;
2694 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002695}
2696
Gustavo Padovand6603662012-05-21 13:58:22 -03002697static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2698 struct l2cap_ctrl *control,
2699 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002700{
Mat Martineau608bcc62012-05-17 20:53:32 -07002701 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2702 event);
2703
2704 switch (event) {
2705 case L2CAP_EV_DATA_REQUEST:
2706 if (chan->tx_send_head == NULL)
2707 chan->tx_send_head = skb_peek(skbs);
2708 /* Queue data, but don't send. */
2709 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2710 break;
2711 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2712 BT_DBG("Enter LOCAL_BUSY");
2713 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2714
2715 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2716 /* The SREJ_SENT state must be aborted if we are to
2717 * enter the LOCAL_BUSY state.
2718 */
2719 l2cap_abort_rx_srej_sent(chan);
2720 }
2721
2722 l2cap_send_ack(chan);
2723
2724 break;
2725 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2726 BT_DBG("Exit LOCAL_BUSY");
2727 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2728
2729 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2730 struct l2cap_ctrl local_control;
2731 memset(&local_control, 0, sizeof(local_control));
2732 local_control.sframe = 1;
2733 local_control.super = L2CAP_SUPER_RR;
2734 local_control.poll = 1;
2735 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002736 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002737
2738 chan->retry_count = 1;
2739 __set_monitor_timer(chan);
2740 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2741 }
2742 break;
2743 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2744 l2cap_process_reqseq(chan, control->reqseq);
2745
2746 /* Fall through */
2747
2748 case L2CAP_EV_RECV_FBIT:
2749 if (control && control->final) {
2750 __clear_monitor_timer(chan);
2751 if (chan->unacked_frames > 0)
2752 __set_retrans_timer(chan);
2753 chan->retry_count = 0;
2754 chan->tx_state = L2CAP_TX_STATE_XMIT;
2755 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2756 }
2757 break;
2758 case L2CAP_EV_EXPLICIT_POLL:
2759 /* Ignore */
2760 break;
2761 case L2CAP_EV_MONITOR_TO:
2762 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2763 l2cap_send_rr_or_rnr(chan, 1);
2764 __set_monitor_timer(chan);
2765 chan->retry_count++;
2766 } else {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02002767 l2cap_send_disconn_req(chan, ECONNABORTED);
Mat Martineau608bcc62012-05-17 20:53:32 -07002768 }
2769 break;
2770 default:
2771 break;
2772 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002773}
2774
Gustavo Padovand6603662012-05-21 13:58:22 -03002775static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2776 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002777{
Mat Martineau608bcc62012-05-17 20:53:32 -07002778 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2779 chan, control, skbs, event, chan->tx_state);
2780
2781 switch (chan->tx_state) {
2782 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002783 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002784 break;
2785 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002786 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002787 break;
2788 default:
2789 /* Ignore event */
2790 break;
2791 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002792}
2793
Mat Martineau4b51dae92012-05-17 20:53:37 -07002794static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2795 struct l2cap_ctrl *control)
2796{
2797 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002798 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002799}
2800
Mat Martineauf80842a2012-05-17 20:53:46 -07002801static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2802 struct l2cap_ctrl *control)
2803{
2804 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002805 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002806}
2807
Linus Torvalds1da177e2005-04-16 15:20:36 -07002808/* Copy frame to all raw sockets on that connection */
2809static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2810{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002811 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002812 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002813
2814 BT_DBG("conn %p", conn);
2815
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002816 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002817
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002818 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002819 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002820 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002821 continue;
2822
2823 /* Don't send frame to the socket it came from */
2824 if (skb->sk == sk)
2825 continue;
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002826 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002827 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002828 continue;
2829
Gustavo Padovan80b98022012-05-27 22:27:51 -03002830 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002831 kfree_skb(nskb);
2832 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002833
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002834 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002835}
2836
2837/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002838static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2839 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002840{
2841 struct sk_buff *skb, **frag;
2842 struct l2cap_cmd_hdr *cmd;
2843 struct l2cap_hdr *lh;
2844 int len, count;
2845
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002846 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2847 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002848
Anderson Lizardo300b9622013-06-02 16:30:40 -04002849 if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2850 return NULL;
2851
Linus Torvalds1da177e2005-04-16 15:20:36 -07002852 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2853 count = min_t(unsigned int, conn->mtu, len);
2854
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002855 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002856 if (!skb)
2857 return NULL;
2858
2859 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002860 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002861
2862 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002863 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002864 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002865 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002866
2867 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2868 cmd->code = code;
2869 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002870 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002871
2872 if (dlen) {
2873 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2874 memcpy(skb_put(skb, count), data, count);
2875 data += count;
2876 }
2877
2878 len -= skb->len;
2879
2880 /* Continuation fragments (no L2CAP header) */
2881 frag = &skb_shinfo(skb)->frag_list;
2882 while (len) {
2883 count = min_t(unsigned int, conn->mtu, len);
2884
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002885 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002886 if (!*frag)
2887 goto fail;
2888
2889 memcpy(skb_put(*frag, count), data, count);
2890
2891 len -= count;
2892 data += count;
2893
2894 frag = &(*frag)->next;
2895 }
2896
2897 return skb;
2898
2899fail:
2900 kfree_skb(skb);
2901 return NULL;
2902}
2903
Gustavo Padovan2d792812012-10-06 10:07:01 +01002904static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2905 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002906{
2907 struct l2cap_conf_opt *opt = *ptr;
2908 int len;
2909
2910 len = L2CAP_CONF_OPT_SIZE + opt->len;
2911 *ptr += len;
2912
2913 *type = opt->type;
2914 *olen = opt->len;
2915
2916 switch (opt->len) {
2917 case 1:
2918 *val = *((u8 *) opt->val);
2919 break;
2920
2921 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002922 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002923 break;
2924
2925 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002926 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927 break;
2928
2929 default:
2930 *val = (unsigned long) opt->val;
2931 break;
2932 }
2933
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002934 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002935 return len;
2936}
2937
Linus Torvalds1da177e2005-04-16 15:20:36 -07002938static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2939{
2940 struct l2cap_conf_opt *opt = *ptr;
2941
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002942 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002943
2944 opt->type = type;
2945 opt->len = len;
2946
2947 switch (len) {
2948 case 1:
2949 *((u8 *) opt->val) = val;
2950 break;
2951
2952 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002953 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002954 break;
2955
2956 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002957 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002958 break;
2959
2960 default:
2961 memcpy(opt->val, (void *) val, len);
2962 break;
2963 }
2964
2965 *ptr += L2CAP_CONF_OPT_SIZE + len;
2966}
2967
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002968static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2969{
2970 struct l2cap_conf_efs efs;
2971
Szymon Janc1ec918c2011-11-16 09:32:21 +01002972 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002973 case L2CAP_MODE_ERTM:
2974 efs.id = chan->local_id;
2975 efs.stype = chan->local_stype;
2976 efs.msdu = cpu_to_le16(chan->local_msdu);
2977 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002978 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002979 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002980 break;
2981
2982 case L2CAP_MODE_STREAMING:
2983 efs.id = 1;
2984 efs.stype = L2CAP_SERV_BESTEFFORT;
2985 efs.msdu = cpu_to_le16(chan->local_msdu);
2986 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2987 efs.acc_lat = 0;
2988 efs.flush_to = 0;
2989 break;
2990
2991 default:
2992 return;
2993 }
2994
2995 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002996 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002997}
2998
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002999static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003000{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003001 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07003002 ack_timer.work);
3003 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003004
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02003005 BT_DBG("chan %p", chan);
3006
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003007 l2cap_chan_lock(chan);
3008
Mat Martineau03625202012-05-17 20:53:51 -07003009 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
3010 chan->last_acked_seq);
3011
3012 if (frames_to_ack)
3013 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003014
3015 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01003016 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03003017}
3018
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03003019int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003020{
Mat Martineau3c588192012-04-11 10:48:42 -07003021 int err;
3022
Mat Martineau105bdf92012-04-27 16:50:48 -07003023 chan->next_tx_seq = 0;
3024 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003025 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003026 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03003027 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03003028 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07003029 chan->last_acked_seq = 0;
3030 chan->sdu = NULL;
3031 chan->sdu_last_frag = NULL;
3032 chan->sdu_len = 0;
3033
Mat Martineaud34c34f2012-05-14 14:49:27 -07003034 skb_queue_head_init(&chan->tx_q);
3035
Mat Martineau08333282012-10-23 15:24:06 -07003036 chan->local_amp_id = 0;
3037 chan->move_id = 0;
3038 chan->move_state = L2CAP_MOVE_STABLE;
3039 chan->move_role = L2CAP_MOVE_ROLE_NONE;
3040
Mat Martineau105bdf92012-04-27 16:50:48 -07003041 if (chan->mode != L2CAP_MODE_ERTM)
3042 return 0;
3043
3044 chan->rx_state = L2CAP_RX_STATE_RECV;
3045 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003046
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03003047 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
3048 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
3049 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003050
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03003051 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03003052
Mat Martineau3c588192012-04-11 10:48:42 -07003053 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
3054 if (err < 0)
3055 return err;
3056
Mat Martineau9dc9aff2012-05-17 16:20:14 -07003057 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
3058 if (err < 0)
3059 l2cap_seq_list_free(&chan->srej_list);
3060
3061 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003062}
3063
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003064static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
3065{
3066 switch (mode) {
3067 case L2CAP_MODE_STREAMING:
3068 case L2CAP_MODE_ERTM:
3069 if (l2cap_mode_supported(mode, remote_feat_mask))
3070 return mode;
3071 /* fall through */
3072 default:
3073 return L2CAP_MODE_BASIC;
3074 }
3075}
3076
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003077static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
3078{
3079 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
3080}
3081
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003082static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
3083{
3084 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
3085}
3086
Mat Martineau36c86c82012-10-23 15:24:20 -07003087static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
3088 struct l2cap_conf_rfc *rfc)
3089{
3090 if (chan->local_amp_id && chan->hs_hcon) {
3091 u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
3092
3093 /* Class 1 devices have must have ERTM timeouts
3094 * exceeding the Link Supervision Timeout. The
3095 * default Link Supervision Timeout for AMP
3096 * controllers is 10 seconds.
3097 *
3098 * Class 1 devices use 0xffffffff for their
3099 * best-effort flush timeout, so the clamping logic
3100 * will result in a timeout that meets the above
3101 * requirement. ERTM timeouts are 16-bit values, so
3102 * the maximum timeout is 65.535 seconds.
3103 */
3104
3105 /* Convert timeout to milliseconds and round */
3106 ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000);
3107
3108 /* This is the recommended formula for class 2 devices
3109 * that start ERTM timers when packets are sent to the
3110 * controller.
3111 */
3112 ertm_to = 3 * ertm_to + 500;
3113
3114 if (ertm_to > 0xffff)
3115 ertm_to = 0xffff;
3116
3117 rfc->retrans_timeout = cpu_to_le16((u16) ertm_to);
3118 rfc->monitor_timeout = rfc->retrans_timeout;
3119 } else {
3120 rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3121 rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3122 }
3123}
3124
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003125static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
3126{
3127 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003128 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003129 /* use extended control field */
3130 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003131 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3132 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003133 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003134 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003135 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3136 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07003137 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003138}
3139
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003140static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003141{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003142 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003143 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003144 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003145 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003146
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03003147 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003148
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003149 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003150 goto done;
3151
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003152 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003153 case L2CAP_MODE_STREAMING:
3154 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003155 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003156 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003157
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003158 if (__l2cap_efs_supported(chan))
3159 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3160
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03003161 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003162 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003163 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003164 break;
3165 }
3166
3167done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003168 if (chan->imtu != L2CAP_DEFAULT_MTU)
3169 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02003170
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003171 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003172 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003173 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003174 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003175 break;
3176
Gustavo F. Padovan62547752010-06-08 20:05:31 -03003177 rfc.mode = L2CAP_MODE_BASIC;
3178 rfc.txwin_size = 0;
3179 rfc.max_transmit = 0;
3180 rfc.retrans_timeout = 0;
3181 rfc.monitor_timeout = 0;
3182 rfc.max_pdu_size = 0;
3183
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003184 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003185 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003186 break;
3187
3188 case L2CAP_MODE_ERTM:
3189 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003190 rfc.max_transmit = chan->max_tx;
Mat Martineau36c86c82012-10-23 15:24:20 -07003191
3192 __l2cap_set_ertm_timeouts(chan, &rfc);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003193
3194 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003195 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3196 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003197 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003198
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003199 l2cap_txwin_setup(chan);
3200
3201 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003202 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003203
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003204 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003205 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003206
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003207 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3208 l2cap_add_opt_efs(&ptr, chan);
3209
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003210 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3211 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003212 chan->tx_win);
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003213
3214 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3215 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003216 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003217 chan->fcs = L2CAP_FCS_NONE;
3218 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3219 chan->fcs);
3220 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003221 break;
3222
3223 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003224 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003225 rfc.mode = L2CAP_MODE_STREAMING;
3226 rfc.txwin_size = 0;
3227 rfc.max_transmit = 0;
3228 rfc.retrans_timeout = 0;
3229 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003230
3231 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003232 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3233 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003234 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003235
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003236 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003237 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003238
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003239 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3240 l2cap_add_opt_efs(&ptr, chan);
3241
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003242 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3243 if (chan->fcs == L2CAP_FCS_NONE ||
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003244 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
Andrei Emeltchenko60918912012-11-29 17:46:06 +02003245 chan->fcs = L2CAP_FCS_NONE;
3246 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3247 chan->fcs);
3248 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003249 break;
3250 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003251
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003252 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003253 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003254
3255 return ptr - data;
3256}
3257
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003258static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003259{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003260 struct l2cap_conf_rsp *rsp = data;
3261 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003262 void *req = chan->conf_req;
3263 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003264 int type, hint, olen;
3265 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003266 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003267 struct l2cap_conf_efs efs;
3268 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003269 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003270 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003271 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003272
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003273 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003274
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003275 while (len >= L2CAP_CONF_OPT_SIZE) {
3276 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003277
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003278 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003279 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003280
3281 switch (type) {
3282 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003283 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003284 break;
3285
3286 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003287 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003288 break;
3289
3290 case L2CAP_CONF_QOS:
3291 break;
3292
Marcel Holtmann6464f352007-10-20 13:39:51 +02003293 case L2CAP_CONF_RFC:
3294 if (olen == sizeof(rfc))
3295 memcpy(&rfc, (void *) val, olen);
3296 break;
3297
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003298 case L2CAP_CONF_FCS:
3299 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003300 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003301 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003302
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003303 case L2CAP_CONF_EFS:
3304 remote_efs = 1;
3305 if (olen == sizeof(efs))
3306 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003307 break;
3308
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003309 case L2CAP_CONF_EWS:
3310 if (!enable_hs)
3311 return -ECONNREFUSED;
3312
3313 set_bit(FLAG_EXT_CTRL, &chan->flags);
3314 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003315 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003316 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003317 break;
3318
3319 default:
3320 if (hint)
3321 break;
3322
3323 result = L2CAP_CONF_UNKNOWN;
3324 *((u8 *) ptr++) = type;
3325 break;
3326 }
3327 }
3328
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003329 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003330 goto done;
3331
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003332 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003333 case L2CAP_MODE_STREAMING:
3334 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003335 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003336 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003337 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003338 break;
3339 }
3340
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003341 if (remote_efs) {
3342 if (__l2cap_efs_supported(chan))
3343 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3344 else
3345 return -ECONNREFUSED;
3346 }
3347
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003348 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003349 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003350
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003351 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003352 }
3353
3354done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003355 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003356 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003357 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003358
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003359 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003360 return -ECONNREFUSED;
3361
Gustavo Padovan2d792812012-10-06 10:07:01 +01003362 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3363 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003364 }
3365
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003366 if (result == L2CAP_CONF_SUCCESS) {
3367 /* Configure output options and let the other side know
3368 * which ones we don't like. */
3369
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003370 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3371 result = L2CAP_CONF_UNACCEPT;
3372 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003373 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003374 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003375 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003376 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003377
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003378 if (remote_efs) {
3379 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003380 efs.stype != L2CAP_SERV_NOTRAFIC &&
3381 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003382
3383 result = L2CAP_CONF_UNACCEPT;
3384
3385 if (chan->num_conf_req >= 1)
3386 return -ECONNREFUSED;
3387
3388 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003389 sizeof(efs),
3390 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003391 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003392 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003393 result = L2CAP_CONF_PENDING;
3394 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003395 }
3396 }
3397
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003398 switch (rfc.mode) {
3399 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003400 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003401 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003402 break;
3403
3404 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003405 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3406 chan->remote_tx_win = rfc.txwin_size;
3407 else
3408 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3409
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003410 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003411
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003412 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003413 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3414 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003415 rfc.max_pdu_size = cpu_to_le16(size);
3416 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003417
Mat Martineau36c86c82012-10-23 15:24:20 -07003418 __l2cap_set_ertm_timeouts(chan, &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003419
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003420 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003421
3422 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003423 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003424
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003425 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3426 chan->remote_id = efs.id;
3427 chan->remote_stype = efs.stype;
3428 chan->remote_msdu = le16_to_cpu(efs.msdu);
3429 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003430 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003431 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003432 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003433 chan->remote_sdu_itime =
3434 le32_to_cpu(efs.sdu_itime);
3435 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003436 sizeof(efs),
3437 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003438 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003439 break;
3440
3441 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003442 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003443 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3444 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003445 rfc.max_pdu_size = cpu_to_le16(size);
3446 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003447
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003448 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003449
Gustavo Padovan2d792812012-10-06 10:07:01 +01003450 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3451 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003452
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003453 break;
3454
3455 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003456 result = L2CAP_CONF_UNACCEPT;
3457
3458 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003459 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003460 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003461
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003462 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003463 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003464 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003465 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003466 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003467 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003468
3469 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003470}
3471
Gustavo Padovan2d792812012-10-06 10:07:01 +01003472static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3473 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003474{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003475 struct l2cap_conf_req *req = data;
3476 void *ptr = req->data;
3477 int type, olen;
3478 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003479 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003480 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003481
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003482 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003483
3484 while (len >= L2CAP_CONF_OPT_SIZE) {
3485 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3486
3487 switch (type) {
3488 case L2CAP_CONF_MTU:
3489 if (val < L2CAP_DEFAULT_MIN_MTU) {
3490 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003491 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003492 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003493 chan->imtu = val;
3494 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003495 break;
3496
3497 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003498 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003499 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003500 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003501 break;
3502
3503 case L2CAP_CONF_RFC:
3504 if (olen == sizeof(rfc))
3505 memcpy(&rfc, (void *)val, olen);
3506
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003507 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003508 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003509 return -ECONNREFUSED;
3510
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003511 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003512
3513 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003514 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003515 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003516
3517 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003518 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003519 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003520 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003521 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003522
3523 case L2CAP_CONF_EFS:
3524 if (olen == sizeof(efs))
3525 memcpy(&efs, (void *)val, olen);
3526
3527 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003528 efs.stype != L2CAP_SERV_NOTRAFIC &&
3529 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003530 return -ECONNREFUSED;
3531
Gustavo Padovan2d792812012-10-06 10:07:01 +01003532 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3533 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003534 break;
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003535
3536 case L2CAP_CONF_FCS:
3537 if (*result == L2CAP_CONF_PENDING)
3538 if (val == L2CAP_FCS_NONE)
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003539 set_bit(CONF_RECV_NO_FCS,
Andrei Emeltchenkocbabee72012-11-29 17:46:07 +02003540 &chan->conf_state);
3541 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003542 }
3543 }
3544
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003545 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003546 return -ECONNREFUSED;
3547
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003548 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003549
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003550 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003551 switch (rfc.mode) {
3552 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003553 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3554 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3555 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003556 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3557 chan->ack_win = min_t(u16, chan->ack_win,
3558 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003559
3560 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3561 chan->local_msdu = le16_to_cpu(efs.msdu);
3562 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003563 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003564 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3565 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003566 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003567 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003568 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003569
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003570 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003571 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003572 }
3573 }
3574
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003575 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003576 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003577
3578 return ptr - data;
3579}
3580
Gustavo Padovan2d792812012-10-06 10:07:01 +01003581static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3582 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003583{
3584 struct l2cap_conf_rsp *rsp = data;
3585 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003586
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003587 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003588
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003589 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003590 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003591 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003592
3593 return ptr - data;
3594}
3595
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003596void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003597{
3598 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003599 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003600 u8 buf[128];
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003601 u8 rsp_code;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003602
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003603 rsp.scid = cpu_to_le16(chan->dcid);
3604 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003605 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3606 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Andrei Emeltchenko439f34a2012-10-31 15:46:28 +02003607
3608 if (chan->hs_hcon)
3609 rsp_code = L2CAP_CREATE_CHAN_RSP;
3610 else
3611 rsp_code = L2CAP_CONN_RSP;
3612
3613 BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3614
3615 l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003616
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003617 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003618 return;
3619
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003620 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003621 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003622 chan->num_conf_req++;
3623}
3624
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003625static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003626{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003627 int type, olen;
3628 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003629 /* Use sane default values in case a misbehaving remote device
3630 * did not send an RFC or extended window size option.
3631 */
3632 u16 txwin_ext = chan->ack_win;
3633 struct l2cap_conf_rfc rfc = {
3634 .mode = chan->mode,
3635 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3636 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3637 .max_pdu_size = cpu_to_le16(chan->imtu),
3638 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3639 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003640
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003641 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003642
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003643 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003644 return;
3645
3646 while (len >= L2CAP_CONF_OPT_SIZE) {
3647 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3648
Mat Martineauc20f8e32012-07-10 05:47:07 -07003649 switch (type) {
3650 case L2CAP_CONF_RFC:
3651 if (olen == sizeof(rfc))
3652 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003653 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003654 case L2CAP_CONF_EWS:
3655 txwin_ext = val;
3656 break;
3657 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003658 }
3659
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003660 switch (rfc.mode) {
3661 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003662 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3663 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003664 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3665 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3666 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3667 else
3668 chan->ack_win = min_t(u16, chan->ack_win,
3669 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003670 break;
3671 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003672 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003673 }
3674}
3675
Gustavo Padovan2d792812012-10-06 10:07:01 +01003676static inline int l2cap_command_rej(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003677 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3678 u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003679{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003680 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003681
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003682 if (cmd_len < sizeof(*rej))
3683 return -EPROTO;
3684
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003685 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003686 return 0;
3687
3688 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003689 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003690 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003691
3692 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003693 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003694
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003695 l2cap_conn_start(conn);
3696 }
3697
3698 return 0;
3699}
3700
Mat Martineau17009152012-10-23 15:24:07 -07003701static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3702 struct l2cap_cmd_hdr *cmd,
3703 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003704{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003705 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3706 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003707 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003708 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003709 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003710
3711 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003712 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003713
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003714 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003715
3716 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003717 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003718 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003719 result = L2CAP_CR_BAD_PSM;
3720 goto sendresp;
3721 }
3722
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003723 parent = pchan->sk;
3724
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003725 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003726 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003727
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003728 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003729 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003730 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003731 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003732 result = L2CAP_CR_SEC_BLOCK;
3733 goto response;
3734 }
3735
Linus Torvalds1da177e2005-04-16 15:20:36 -07003736 result = L2CAP_CR_NO_MEM;
3737
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003738 /* Check if we already have channel with that dcid */
3739 if (__l2cap_get_chan_by_dcid(conn, scid))
3740 goto response;
3741
Gustavo Padovan80b98022012-05-27 22:27:51 -03003742 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003743 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003744 goto response;
3745
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003746 sk = chan->sk;
3747
Linus Torvalds1da177e2005-04-16 15:20:36 -07003748 hci_conn_hold(conn->hcon);
3749
Linus Torvalds1da177e2005-04-16 15:20:36 -07003750 bacpy(&bt_sk(sk)->src, conn->src);
3751 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003752 chan->psm = psm;
3753 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003754 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003755
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003756 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003757
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003758 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003759
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003760 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003761
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003762 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003763
Marcel Holtmann984947d2009-02-06 23:35:19 +01003764 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003765 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003766 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003767 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003768 result = L2CAP_CR_PEND;
3769 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003770 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003771 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003772 /* Force pending result for AMP controllers.
3773 * The connection will succeed after the
3774 * physical link is up.
3775 */
3776 if (amp_id) {
3777 __l2cap_state_change(chan, BT_CONNECT2);
3778 result = L2CAP_CR_PEND;
3779 } else {
3780 __l2cap_state_change(chan, BT_CONFIG);
3781 result = L2CAP_CR_SUCCESS;
3782 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003783 status = L2CAP_CS_NO_INFO;
3784 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003785 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003786 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003787 result = L2CAP_CR_PEND;
3788 status = L2CAP_CS_AUTHEN_PEND;
3789 }
3790 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003791 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003792 result = L2CAP_CR_PEND;
3793 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003794 }
3795
Linus Torvalds1da177e2005-04-16 15:20:36 -07003796response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003797 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003798 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003799
3800sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003801 rsp.scid = cpu_to_le16(scid);
3802 rsp.dcid = cpu_to_le16(dcid);
3803 rsp.result = cpu_to_le16(result);
3804 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003805 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003806
3807 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3808 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003809 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003810
3811 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3812 conn->info_ident = l2cap_get_ident(conn);
3813
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003814 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003815
Gustavo Padovan2d792812012-10-06 10:07:01 +01003816 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3817 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003818 }
3819
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003820 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003821 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003822 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003823 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003824 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003825 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003826 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003827 }
Mat Martineau17009152012-10-23 15:24:07 -07003828
3829 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003830}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003831
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003832static int l2cap_connect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003833 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003834{
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303835 struct hci_dev *hdev = conn->hcon->hdev;
3836 struct hci_conn *hcon = conn->hcon;
3837
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003838 if (cmd_len < sizeof(struct l2cap_conn_req))
3839 return -EPROTO;
3840
Jaganath Kanakkassery7b064ed2013-01-10 10:28:35 +05303841 hci_dev_lock(hdev);
3842 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
3843 !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
3844 mgmt_device_connected(hdev, &hcon->dst, hcon->type,
3845 hcon->dst_type, 0, NULL, 0,
3846 hcon->dev_class);
3847 hci_dev_unlock(hdev);
3848
Gustavo Padovan300229f2012-10-12 19:40:40 +08003849 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003850 return 0;
3851}
3852
Mat Martineau5909cf32012-10-23 15:24:08 -07003853static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003854 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3855 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003856{
3857 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3858 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003859 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003860 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003861 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003862
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003863 if (cmd_len < sizeof(*rsp))
3864 return -EPROTO;
3865
Linus Torvalds1da177e2005-04-16 15:20:36 -07003866 scid = __le16_to_cpu(rsp->scid);
3867 dcid = __le16_to_cpu(rsp->dcid);
3868 result = __le16_to_cpu(rsp->result);
3869 status = __le16_to_cpu(rsp->status);
3870
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003871 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 +01003872 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003873
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003874 mutex_lock(&conn->chan_lock);
3875
Linus Torvalds1da177e2005-04-16 15:20:36 -07003876 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003877 chan = __l2cap_get_chan_by_scid(conn, scid);
3878 if (!chan) {
3879 err = -EFAULT;
3880 goto unlock;
3881 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003882 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003883 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3884 if (!chan) {
3885 err = -EFAULT;
3886 goto unlock;
3887 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003888 }
3889
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003890 err = 0;
3891
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003892 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003893
Linus Torvalds1da177e2005-04-16 15:20:36 -07003894 switch (result) {
3895 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003896 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003897 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003898 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003899 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003900
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003901 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003902 break;
3903
Linus Torvalds1da177e2005-04-16 15:20:36 -07003904 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003905 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003906 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003907 break;
3908
3909 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003910 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003911 break;
3912
3913 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003914 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003915 break;
3916 }
3917
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003918 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003919
3920unlock:
3921 mutex_unlock(&conn->chan_lock);
3922
3923 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003924}
3925
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003926static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003927{
3928 /* FCS is enabled only in ERTM or streaming mode, if one or both
3929 * sides request it.
3930 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003931 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003932 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenkof2592d32012-11-29 17:46:08 +02003933 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003934 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003935}
3936
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003937static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3938 u8 ident, u16 flags)
3939{
3940 struct l2cap_conn *conn = chan->conn;
3941
3942 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3943 flags);
3944
3945 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3946 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3947
3948 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
3949 l2cap_build_conf_rsp(chan, data,
3950 L2CAP_CONF_SUCCESS, flags), data);
3951}
3952
Gustavo Padovan2d792812012-10-06 10:07:01 +01003953static inline int l2cap_config_req(struct l2cap_conn *conn,
3954 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3955 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003956{
3957 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3958 u16 dcid, flags;
3959 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003960 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003961 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003962
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003963 if (cmd_len < sizeof(*req))
3964 return -EPROTO;
3965
Linus Torvalds1da177e2005-04-16 15:20:36 -07003966 dcid = __le16_to_cpu(req->dcid);
3967 flags = __le16_to_cpu(req->flags);
3968
3969 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3970
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003971 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003972 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003973 return -ENOENT;
3974
David S. Miller033b1142011-07-21 13:38:42 -07003975 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003976 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003977
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003978 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003979 rej.scid = cpu_to_le16(chan->scid);
3980 rej.dcid = cpu_to_le16(chan->dcid);
3981
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003982 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003983 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003984 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003985 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003986
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003987 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003988 len = cmd_len - sizeof(*req);
Johan Hedbergcb3b3152013-05-28 13:46:30 +03003989 if (chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003990 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003991 l2cap_build_conf_rsp(chan, rsp,
3992 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003993 goto unlock;
3994 }
3995
3996 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003997 memcpy(chan->conf_req + chan->conf_len, req->data, len);
3998 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003999
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004000 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004001 /* Incomplete config. Send empty response. */
4002 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004003 l2cap_build_conf_rsp(chan, rsp,
4004 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004005 goto unlock;
4006 }
4007
4008 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004009 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004010 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004011 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004012 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004013 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004014
Mat Martineau1500109b2012-10-23 15:24:15 -07004015 chan->ident = cmd->ident;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004016 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004017 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004018
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004019 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004020 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02004021
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004022 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02004023 goto unlock;
4024
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004025 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004026 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004027
Mat Martineau105bdf92012-04-27 16:50:48 -07004028 if (chan->mode == L2CAP_MODE_ERTM ||
4029 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004030 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004031
Mat Martineau3c588192012-04-11 10:48:42 -07004032 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004033 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004034 else
4035 l2cap_chan_ready(chan);
4036
Marcel Holtmann876d9482007-10-20 13:35:42 +02004037 goto unlock;
4038 }
4039
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004040 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02004041 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004042 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004043 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004044 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004045 }
4046
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004047 /* Got Conf Rsp PENDING from remote side and asume we sent
4048 Conf Rsp PENDING in the code above */
4049 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03004050 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004051
4052 /* check compatibility */
4053
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004054 /* Send rsp for BR/EDR channel */
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004055 if (!chan->hs_hcon)
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004056 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
4057 else
4058 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004059 }
4060
Linus Torvalds1da177e2005-04-16 15:20:36 -07004061unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004062 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004063 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004064}
4065
Gustavo Padovan2d792812012-10-06 10:07:01 +01004066static inline int l2cap_config_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004067 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4068 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004069{
4070 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
4071 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004072 struct l2cap_chan *chan;
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004073 int len = cmd_len - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07004074 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004075
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004076 if (cmd_len < sizeof(*rsp))
4077 return -EPROTO;
4078
Linus Torvalds1da177e2005-04-16 15:20:36 -07004079 scid = __le16_to_cpu(rsp->scid);
4080 flags = __le16_to_cpu(rsp->flags);
4081 result = __le16_to_cpu(rsp->result);
4082
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02004083 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
4084 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004085
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03004086 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004087 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004088 return 0;
4089
4090 switch (result) {
4091 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004092 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004093 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004094 break;
4095
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004096 case L2CAP_CONF_PENDING:
4097 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
4098
4099 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
4100 char buf[64];
4101
4102 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004103 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004104 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004105 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004106 goto done;
4107 }
4108
Andrei Emeltchenkof351bc72012-10-31 15:46:35 +02004109 if (!chan->hs_hcon) {
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03004110 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
4111 0);
Andrei Emeltchenko5ce66b52012-10-31 15:46:30 +02004112 } else {
4113 if (l2cap_check_efs(chan)) {
4114 amp_create_logical_link(chan);
4115 chan->ident = cmd->ident;
4116 }
4117 }
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03004118 }
4119 goto done;
4120
Linus Torvalds1da177e2005-04-16 15:20:36 -07004121 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004122 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004123 char req[64];
4124
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004125 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004126 l2cap_send_disconn_req(chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02004127 goto done;
4128 }
4129
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004130 /* throw out any old stored conf requests */
4131 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03004132 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004133 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004134 if (len < 0) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004135 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004136 goto done;
4137 }
4138
4139 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01004140 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03004141 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03004142 if (result != L2CAP_CONF_SUCCESS)
4143 goto done;
4144 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004145 }
4146
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09004147 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004148 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02004149
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08004150 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004151 l2cap_send_disconn_req(chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004152 goto done;
4153 }
4154
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03004155 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004156 goto done;
4157
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004158 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004159
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03004160 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004161 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004162
Mat Martineau105bdf92012-04-27 16:50:48 -07004163 if (chan->mode == L2CAP_MODE_ERTM ||
4164 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07004165 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03004166
Mat Martineau3c588192012-04-11 10:48:42 -07004167 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004168 l2cap_send_disconn_req(chan, -err);
Mat Martineau3c588192012-04-11 10:48:42 -07004169 else
4170 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004171 }
4172
4173done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004174 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07004175 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004176}
4177
Gustavo Padovan2d792812012-10-06 10:07:01 +01004178static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004179 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4180 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004181{
4182 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
4183 struct l2cap_disconn_rsp rsp;
4184 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004185 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004186 struct sock *sk;
4187
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004188 if (cmd_len != sizeof(*req))
4189 return -EPROTO;
4190
Linus Torvalds1da177e2005-04-16 15:20:36 -07004191 scid = __le16_to_cpu(req->scid);
4192 dcid = __le16_to_cpu(req->dcid);
4193
4194 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
4195
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004196 mutex_lock(&conn->chan_lock);
4197
4198 chan = __l2cap_get_chan_by_scid(conn, dcid);
4199 if (!chan) {
4200 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004201 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004202 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004203
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004204 l2cap_chan_lock(chan);
4205
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004206 sk = chan->sk;
4207
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03004208 rsp.dcid = cpu_to_le16(chan->scid);
4209 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004210 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
4211
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004212 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004213 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004214 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004215
Mat Martineau61d6ef32012-04-27 16:50:50 -07004216 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004217 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004218
4219 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004220
Gustavo Padovan80b98022012-05-27 22:27:51 -03004221 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004222 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004223
4224 mutex_unlock(&conn->chan_lock);
4225
Linus Torvalds1da177e2005-04-16 15:20:36 -07004226 return 0;
4227}
4228
Gustavo Padovan2d792812012-10-06 10:07:01 +01004229static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004230 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4231 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004232{
4233 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
4234 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004235 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004236
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004237 if (cmd_len != sizeof(*rsp))
4238 return -EPROTO;
4239
Linus Torvalds1da177e2005-04-16 15:20:36 -07004240 scid = __le16_to_cpu(rsp->scid);
4241 dcid = __le16_to_cpu(rsp->dcid);
4242
4243 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
4244
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004245 mutex_lock(&conn->chan_lock);
4246
4247 chan = __l2cap_get_chan_by_scid(conn, scid);
4248 if (!chan) {
4249 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004250 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004251 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004252
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004253 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004254
Mat Martineau61d6ef32012-04-27 16:50:50 -07004255 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004256 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004257
4258 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004259
Gustavo Padovan80b98022012-05-27 22:27:51 -03004260 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004261 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004262
4263 mutex_unlock(&conn->chan_lock);
4264
Linus Torvalds1da177e2005-04-16 15:20:36 -07004265 return 0;
4266}
4267
Gustavo Padovan2d792812012-10-06 10:07:01 +01004268static inline int l2cap_information_req(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004269 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4270 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004271{
4272 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004273 u16 type;
4274
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004275 if (cmd_len != sizeof(*req))
4276 return -EPROTO;
4277
Linus Torvalds1da177e2005-04-16 15:20:36 -07004278 type = __le16_to_cpu(req->type);
4279
4280 BT_DBG("type 0x%4.4x", type);
4281
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004282 if (type == L2CAP_IT_FEAT_MASK) {
4283 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004284 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004285 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004286 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4287 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004288 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004289 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004290 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004291 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004292 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004293 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004294
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004295 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004296 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4297 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004298 } else if (type == L2CAP_IT_FIXED_CHAN) {
4299 u8 buf[12];
4300 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004301
4302 if (enable_hs)
4303 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4304 else
4305 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4306
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004307 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4308 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004309 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004310 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4311 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004312 } else {
4313 struct l2cap_info_rsp rsp;
4314 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004315 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004316 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4317 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004318 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004319
4320 return 0;
4321}
4322
Gustavo Padovan2d792812012-10-06 10:07:01 +01004323static inline int l2cap_information_rsp(struct l2cap_conn *conn,
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004324 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4325 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004326{
4327 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4328 u16 type, result;
4329
Johan Hedbergcb3b3152013-05-28 13:46:30 +03004330 if (cmd_len != sizeof(*rsp))
4331 return -EPROTO;
4332
Linus Torvalds1da177e2005-04-16 15:20:36 -07004333 type = __le16_to_cpu(rsp->type);
4334 result = __le16_to_cpu(rsp->result);
4335
4336 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4337
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004338 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4339 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004340 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004341 return 0;
4342
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004343 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004344
Ville Tervoadb08ed2010-08-04 09:43:33 +03004345 if (result != L2CAP_IR_SUCCESS) {
4346 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4347 conn->info_ident = 0;
4348
4349 l2cap_conn_start(conn);
4350
4351 return 0;
4352 }
4353
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004354 switch (type) {
4355 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004356 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004357
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004358 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004359 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004360 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004361
4362 conn->info_ident = l2cap_get_ident(conn);
4363
4364 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004365 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004366 } else {
4367 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4368 conn->info_ident = 0;
4369
4370 l2cap_conn_start(conn);
4371 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004372 break;
4373
4374 case L2CAP_IT_FIXED_CHAN:
4375 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004376 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004377 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004378
4379 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004380 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004381 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004382
Linus Torvalds1da177e2005-04-16 15:20:36 -07004383 return 0;
4384}
4385
Mat Martineau17009152012-10-23 15:24:07 -07004386static int l2cap_create_channel_req(struct l2cap_conn *conn,
4387 struct l2cap_cmd_hdr *cmd,
4388 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004389{
4390 struct l2cap_create_chan_req *req = data;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004391 struct l2cap_create_chan_rsp rsp;
Mat Martineau17009152012-10-23 15:24:07 -07004392 struct l2cap_chan *chan;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004393 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004394 u16 psm, scid;
4395
4396 if (cmd_len != sizeof(*req))
4397 return -EPROTO;
4398
4399 if (!enable_hs)
4400 return -EINVAL;
4401
4402 psm = le16_to_cpu(req->psm);
4403 scid = le16_to_cpu(req->scid);
4404
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004405 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 -07004406
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004407 /* For controller id 0 make BR/EDR connection */
4408 if (req->amp_id == HCI_BREDR_ID) {
4409 l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4410 req->amp_id);
4411 return 0;
4412 }
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004413
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004414 /* Validate AMP controller id */
4415 hdev = hci_dev_get(req->amp_id);
4416 if (!hdev)
4417 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004418
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004419 if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) {
Mat Martineau17009152012-10-23 15:24:07 -07004420 hci_dev_put(hdev);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004421 goto error;
Mat Martineau17009152012-10-23 15:24:07 -07004422 }
4423
4424 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4425 req->amp_id);
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004426 if (chan) {
4427 struct amp_mgr *mgr = conn->hcon->amp_mgr;
4428 struct hci_conn *hs_hcon;
4429
4430 hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, conn->dst);
4431 if (!hs_hcon) {
4432 hci_dev_put(hdev);
4433 return -EFAULT;
4434 }
4435
4436 BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon);
4437
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004438 mgr->bredr_chan = chan;
4439 chan->hs_hcon = hs_hcon;
Andrei Emeltchenkofd45bf42012-11-20 17:16:22 +02004440 chan->fcs = L2CAP_FCS_NONE;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004441 conn->mtu = hdev->block_mtu;
4442 }
4443
4444 hci_dev_put(hdev);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004445
4446 return 0;
Andrei Emeltchenko6e1df6a2012-11-01 15:37:02 +02004447
4448error:
4449 rsp.dcid = 0;
4450 rsp.scid = cpu_to_le16(scid);
4451 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4452 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4453
4454 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4455 sizeof(rsp), &rsp);
4456
4457 return -EFAULT;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004458}
4459
Mat Martineau8eb200b2012-10-23 15:24:17 -07004460static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id)
4461{
4462 struct l2cap_move_chan_req req;
4463 u8 ident;
4464
4465 BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id);
4466
4467 ident = l2cap_get_ident(chan->conn);
4468 chan->ident = ident;
4469
4470 req.icid = cpu_to_le16(chan->scid);
4471 req.dest_amp_id = dest_amp_id;
4472
4473 l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req),
4474 &req);
4475
4476 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4477}
4478
Mat Martineau1500109b2012-10-23 15:24:15 -07004479static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004480{
4481 struct l2cap_move_chan_rsp rsp;
4482
Mat Martineau1500109b2012-10-23 15:24:15 -07004483 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004484
Mat Martineau1500109b2012-10-23 15:24:15 -07004485 rsp.icid = cpu_to_le16(chan->dcid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004486 rsp.result = cpu_to_le16(result);
4487
Mat Martineau1500109b2012-10-23 15:24:15 -07004488 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP,
4489 sizeof(rsp), &rsp);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004490}
4491
Mat Martineau5b155ef2012-10-23 15:24:14 -07004492static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004493{
4494 struct l2cap_move_chan_cfm cfm;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004495
Mat Martineau5b155ef2012-10-23 15:24:14 -07004496 BT_DBG("chan %p, result 0x%4.4x", chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004497
Mat Martineau5b155ef2012-10-23 15:24:14 -07004498 chan->ident = l2cap_get_ident(chan->conn);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004499
Mat Martineau5b155ef2012-10-23 15:24:14 -07004500 cfm.icid = cpu_to_le16(chan->scid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004501 cfm.result = cpu_to_le16(result);
4502
Mat Martineau5b155ef2012-10-23 15:24:14 -07004503 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM,
4504 sizeof(cfm), &cfm);
4505
4506 __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
4507}
4508
4509static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid)
4510{
4511 struct l2cap_move_chan_cfm cfm;
4512
4513 BT_DBG("conn %p, icid 0x%4.4x", conn, icid);
4514
4515 cfm.icid = cpu_to_le16(icid);
4516 cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED);
4517
4518 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM,
4519 sizeof(cfm), &cfm);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004520}
4521
4522static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004523 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004524{
4525 struct l2cap_move_chan_cfm_rsp rsp;
4526
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004527 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004528
4529 rsp.icid = cpu_to_le16(icid);
4530 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4531}
4532
Mat Martineau5f3847a2012-10-23 15:24:12 -07004533static void __release_logical_link(struct l2cap_chan *chan)
4534{
4535 chan->hs_hchan = NULL;
4536 chan->hs_hcon = NULL;
4537
4538 /* Placeholder - release the logical link */
4539}
4540
Mat Martineau1500109b2012-10-23 15:24:15 -07004541static void l2cap_logical_fail(struct l2cap_chan *chan)
4542{
4543 /* Logical link setup failed */
4544 if (chan->state != BT_CONNECTED) {
4545 /* Create channel failure, disconnect */
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004546 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineau1500109b2012-10-23 15:24:15 -07004547 return;
4548 }
4549
4550 switch (chan->move_role) {
4551 case L2CAP_MOVE_ROLE_RESPONDER:
4552 l2cap_move_done(chan);
4553 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP);
4554 break;
4555 case L2CAP_MOVE_ROLE_INITIATOR:
4556 if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
4557 chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
4558 /* Remote has only sent pending or
4559 * success responses, clean up
4560 */
4561 l2cap_move_done(chan);
4562 }
4563
4564 /* Other amp move states imply that the move
4565 * has already aborted
4566 */
4567 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4568 break;
4569 }
4570}
4571
4572static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4573 struct hci_chan *hchan)
4574{
4575 struct l2cap_conf_rsp rsp;
Mat Martineau1500109b2012-10-23 15:24:15 -07004576
Andrei Emeltchenko336178a2012-10-31 15:46:27 +02004577 chan->hs_hchan = hchan;
Mat Martineau1500109b2012-10-23 15:24:15 -07004578 chan->hs_hcon->l2cap_data = chan->conn;
4579
Andrei Emeltchenko35ba9562012-10-25 15:20:43 +03004580 l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
Mat Martineau1500109b2012-10-23 15:24:15 -07004581
4582 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Andrei Emeltchenkofe79c6f2012-10-25 15:20:42 +03004583 int err;
Mat Martineau1500109b2012-10-23 15:24:15 -07004584
4585 set_default_fcs(chan);
4586
4587 err = l2cap_ertm_init(chan);
4588 if (err < 0)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02004589 l2cap_send_disconn_req(chan, -err);
Mat Martineau1500109b2012-10-23 15:24:15 -07004590 else
4591 l2cap_chan_ready(chan);
4592 }
4593}
4594
4595static void l2cap_logical_finish_move(struct l2cap_chan *chan,
4596 struct hci_chan *hchan)
4597{
4598 chan->hs_hcon = hchan->conn;
4599 chan->hs_hcon->l2cap_data = chan->conn;
4600
4601 BT_DBG("move_state %d", chan->move_state);
4602
4603 switch (chan->move_state) {
4604 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4605 /* Move confirm will be sent after a success
4606 * response is received
4607 */
4608 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4609 break;
4610 case L2CAP_MOVE_WAIT_LOGICAL_CFM:
4611 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4612 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4613 } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
4614 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4615 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4616 } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4617 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4618 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4619 }
4620 break;
4621 default:
4622 /* Move was not in expected state, free the channel */
4623 __release_logical_link(chan);
4624
4625 chan->move_state = L2CAP_MOVE_STABLE;
4626 }
4627}
4628
4629/* Call with chan locked */
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004630void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
4631 u8 status)
Mat Martineau5b155ef2012-10-23 15:24:14 -07004632{
Mat Martineau1500109b2012-10-23 15:24:15 -07004633 BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
4634
4635 if (status) {
4636 l2cap_logical_fail(chan);
4637 __release_logical_link(chan);
4638 return;
4639 }
4640
4641 if (chan->state != BT_CONNECTED) {
4642 /* Ignore logical link if channel is on BR/EDR */
4643 if (chan->local_amp_id)
4644 l2cap_logical_finish_create(chan, hchan);
4645 } else {
4646 l2cap_logical_finish_move(chan, hchan);
4647 }
Mat Martineau5b155ef2012-10-23 15:24:14 -07004648}
4649
Mat Martineau3f7a56c2012-10-23 15:24:23 -07004650void l2cap_move_start(struct l2cap_chan *chan)
4651{
4652 BT_DBG("chan %p", chan);
4653
4654 if (chan->local_amp_id == HCI_BREDR_ID) {
4655 if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
4656 return;
4657 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4658 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4659 /* Placeholder - start physical link setup */
4660 } else {
4661 chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
4662 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4663 chan->move_id = 0;
4664 l2cap_move_setup(chan);
4665 l2cap_send_move_chan_req(chan, 0);
4666 }
4667}
4668
Mat Martineau8eb200b2012-10-23 15:24:17 -07004669static void l2cap_do_create(struct l2cap_chan *chan, int result,
4670 u8 local_amp_id, u8 remote_amp_id)
4671{
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004672 BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state),
4673 local_amp_id, remote_amp_id);
4674
Andrei Emeltchenko12d6cc62012-11-14 17:39:31 +02004675 chan->fcs = L2CAP_FCS_NONE;
4676
Andrei Emeltchenko62748ca2012-11-20 17:16:19 +02004677 /* Outgoing channel on AMP */
4678 if (chan->state == BT_CONNECT) {
4679 if (result == L2CAP_CR_SUCCESS) {
4680 chan->local_amp_id = local_amp_id;
4681 l2cap_send_create_chan_req(chan, remote_amp_id);
4682 } else {
4683 /* Revert to BR/EDR connect */
4684 l2cap_send_conn_req(chan);
4685 }
4686
4687 return;
4688 }
4689
4690 /* Incoming channel on AMP */
4691 if (__l2cap_no_conn_pending(chan)) {
Mat Martineau8eb200b2012-10-23 15:24:17 -07004692 struct l2cap_conn_rsp rsp;
4693 char buf[128];
4694 rsp.scid = cpu_to_le16(chan->dcid);
4695 rsp.dcid = cpu_to_le16(chan->scid);
4696
Mat Martineau8eb200b2012-10-23 15:24:17 -07004697 if (result == L2CAP_CR_SUCCESS) {
4698 /* Send successful response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004699 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
4700 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004701 } else {
4702 /* Send negative response */
Andrei Emeltchenko62cd50e2012-11-14 17:39:32 +02004703 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4704 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineau8eb200b2012-10-23 15:24:17 -07004705 }
4706
4707 l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP,
4708 sizeof(rsp), &rsp);
4709
4710 if (result == L2CAP_CR_SUCCESS) {
4711 __l2cap_state_change(chan, BT_CONFIG);
4712 set_bit(CONF_REQ_SENT, &chan->conf_state);
4713 l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
4714 L2CAP_CONF_REQ,
4715 l2cap_build_conf_req(chan, buf), buf);
4716 chan->num_conf_req++;
4717 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004718 }
4719}
4720
4721static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id,
4722 u8 remote_amp_id)
4723{
4724 l2cap_move_setup(chan);
4725 chan->move_id = local_amp_id;
4726 chan->move_state = L2CAP_MOVE_WAIT_RSP;
4727
4728 l2cap_send_move_chan_req(chan, remote_amp_id);
4729}
4730
4731static void l2cap_do_move_respond(struct l2cap_chan *chan, int result)
4732{
4733 struct hci_chan *hchan = NULL;
4734
4735 /* Placeholder - get hci_chan for logical link */
4736
4737 if (hchan) {
4738 if (hchan->state == BT_CONNECTED) {
4739 /* Logical link is ready to go */
4740 chan->hs_hcon = hchan->conn;
4741 chan->hs_hcon->l2cap_data = chan->conn;
4742 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4743 l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS);
4744
4745 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4746 } else {
4747 /* Wait for logical link to be ready */
4748 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4749 }
4750 } else {
4751 /* Logical link not available */
4752 l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED);
4753 }
4754}
4755
4756static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
4757{
4758 if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
4759 u8 rsp_result;
4760 if (result == -EINVAL)
4761 rsp_result = L2CAP_MR_BAD_ID;
4762 else
4763 rsp_result = L2CAP_MR_NOT_ALLOWED;
4764
4765 l2cap_send_move_chan_rsp(chan, rsp_result);
4766 }
4767
4768 chan->move_role = L2CAP_MOVE_ROLE_NONE;
4769 chan->move_state = L2CAP_MOVE_STABLE;
4770
4771 /* Restart data transmission */
4772 l2cap_ertm_send(chan);
4773}
4774
Andrei Emeltchenkoa514b172012-11-14 17:39:30 +02004775/* Invoke with locked chan */
4776void __l2cap_physical_cfm(struct l2cap_chan *chan, int result)
Mat Martineau8eb200b2012-10-23 15:24:17 -07004777{
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004778 u8 local_amp_id = chan->local_amp_id;
Andrei Emeltchenkofffadc02012-11-01 15:37:03 +02004779 u8 remote_amp_id = chan->remote_amp_id;
Andrei Emeltchenko770bfef2012-10-31 15:46:29 +02004780
Mat Martineau8eb200b2012-10-23 15:24:17 -07004781 BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
4782 chan, result, local_amp_id, remote_amp_id);
4783
Mat Martineau8eb200b2012-10-23 15:24:17 -07004784 if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) {
4785 l2cap_chan_unlock(chan);
4786 return;
4787 }
4788
4789 if (chan->state != BT_CONNECTED) {
4790 l2cap_do_create(chan, result, local_amp_id, remote_amp_id);
4791 } else if (result != L2CAP_MR_SUCCESS) {
4792 l2cap_do_move_cancel(chan, result);
4793 } else {
4794 switch (chan->move_role) {
4795 case L2CAP_MOVE_ROLE_INITIATOR:
4796 l2cap_do_move_initiate(chan, local_amp_id,
4797 remote_amp_id);
4798 break;
4799 case L2CAP_MOVE_ROLE_RESPONDER:
4800 l2cap_do_move_respond(chan, result);
4801 break;
4802 default:
4803 l2cap_do_move_cancel(chan, result);
4804 break;
4805 }
4806 }
Mat Martineau8eb200b2012-10-23 15:24:17 -07004807}
4808
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004809static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004810 struct l2cap_cmd_hdr *cmd,
4811 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004812{
4813 struct l2cap_move_chan_req *req = data;
Mat Martineau1500109b2012-10-23 15:24:15 -07004814 struct l2cap_move_chan_rsp rsp;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004815 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004816 u16 icid = 0;
4817 u16 result = L2CAP_MR_NOT_ALLOWED;
4818
4819 if (cmd_len != sizeof(*req))
4820 return -EPROTO;
4821
4822 icid = le16_to_cpu(req->icid);
4823
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004824 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004825
4826 if (!enable_hs)
4827 return -EINVAL;
4828
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004829 chan = l2cap_get_chan_by_dcid(conn, icid);
4830 if (!chan) {
Mat Martineau1500109b2012-10-23 15:24:15 -07004831 rsp.icid = cpu_to_le16(icid);
4832 rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED);
4833 l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP,
4834 sizeof(rsp), &rsp);
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004835 return 0;
4836 }
4837
Mat Martineau1500109b2012-10-23 15:24:15 -07004838 chan->ident = cmd->ident;
4839
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004840 if (chan->scid < L2CAP_CID_DYN_START ||
4841 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4842 (chan->mode != L2CAP_MODE_ERTM &&
4843 chan->mode != L2CAP_MODE_STREAMING)) {
4844 result = L2CAP_MR_NOT_ALLOWED;
4845 goto send_move_response;
4846 }
4847
4848 if (chan->local_amp_id == req->dest_amp_id) {
4849 result = L2CAP_MR_SAME_ID;
4850 goto send_move_response;
4851 }
4852
4853 if (req->dest_amp_id) {
4854 struct hci_dev *hdev;
4855 hdev = hci_dev_get(req->dest_amp_id);
4856 if (!hdev || hdev->dev_type != HCI_AMP ||
4857 !test_bit(HCI_UP, &hdev->flags)) {
4858 if (hdev)
4859 hci_dev_put(hdev);
4860
4861 result = L2CAP_MR_BAD_ID;
4862 goto send_move_response;
4863 }
4864 hci_dev_put(hdev);
4865 }
4866
4867 /* Detect a move collision. Only send a collision response
4868 * if this side has "lost", otherwise proceed with the move.
4869 * The winner has the larger bd_addr.
4870 */
4871 if ((__chan_is_moving(chan) ||
4872 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
4873 bacmp(conn->src, conn->dst) > 0) {
4874 result = L2CAP_MR_COLLISION;
4875 goto send_move_response;
4876 }
4877
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004878 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4879 l2cap_move_setup(chan);
4880 chan->move_id = req->dest_amp_id;
4881 icid = chan->dcid;
4882
4883 if (!req->dest_amp_id) {
4884 /* Moving to BR/EDR */
4885 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4886 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4887 result = L2CAP_MR_PEND;
4888 } else {
4889 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4890 result = L2CAP_MR_SUCCESS;
4891 }
4892 } else {
4893 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4894 /* Placeholder - uncomment when amp functions are available */
4895 /*amp_accept_physical(chan, req->dest_amp_id);*/
4896 result = L2CAP_MR_PEND;
4897 }
4898
4899send_move_response:
Mat Martineau1500109b2012-10-23 15:24:15 -07004900 l2cap_send_move_chan_rsp(chan, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004901
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004902 l2cap_chan_unlock(chan);
4903
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004904 return 0;
4905}
4906
Mat Martineau5b155ef2012-10-23 15:24:14 -07004907static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
4908{
4909 struct l2cap_chan *chan;
4910 struct hci_chan *hchan = NULL;
4911
4912 chan = l2cap_get_chan_by_scid(conn, icid);
4913 if (!chan) {
4914 l2cap_send_move_chan_cfm_icid(conn, icid);
4915 return;
4916 }
4917
4918 __clear_chan_timer(chan);
4919 if (result == L2CAP_MR_PEND)
4920 __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT);
4921
4922 switch (chan->move_state) {
4923 case L2CAP_MOVE_WAIT_LOGICAL_COMP:
4924 /* Move confirm will be sent when logical link
4925 * is complete.
4926 */
4927 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4928 break;
4929 case L2CAP_MOVE_WAIT_RSP_SUCCESS:
4930 if (result == L2CAP_MR_PEND) {
4931 break;
4932 } else if (test_bit(CONN_LOCAL_BUSY,
4933 &chan->conn_state)) {
4934 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4935 } else {
4936 /* Logical link is up or moving to BR/EDR,
4937 * proceed with move
4938 */
4939 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
4940 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4941 }
4942 break;
4943 case L2CAP_MOVE_WAIT_RSP:
4944 /* Moving to AMP */
4945 if (result == L2CAP_MR_SUCCESS) {
4946 /* Remote is ready, send confirm immediately
4947 * after logical link is ready
4948 */
4949 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM;
4950 } else {
4951 /* Both logical link and move success
4952 * are required to confirm
4953 */
4954 chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP;
4955 }
4956
4957 /* Placeholder - get hci_chan for logical link */
4958 if (!hchan) {
4959 /* Logical link not available */
4960 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4961 break;
4962 }
4963
4964 /* If the logical link is not yet connected, do not
4965 * send confirmation.
4966 */
4967 if (hchan->state != BT_CONNECTED)
4968 break;
4969
4970 /* Logical link is already ready to go */
4971
4972 chan->hs_hcon = hchan->conn;
4973 chan->hs_hcon->l2cap_data = chan->conn;
4974
4975 if (result == L2CAP_MR_SUCCESS) {
4976 /* Can confirm now */
4977 l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED);
4978 } else {
4979 /* Now only need move success
4980 * to confirm
4981 */
4982 chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
4983 }
4984
4985 l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS);
4986 break;
4987 default:
4988 /* Any other amp move state means the move failed. */
4989 chan->move_id = chan->local_amp_id;
4990 l2cap_move_done(chan);
4991 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
4992 }
4993
4994 l2cap_chan_unlock(chan);
4995}
4996
4997static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
4998 u16 result)
4999{
5000 struct l2cap_chan *chan;
5001
5002 chan = l2cap_get_chan_by_ident(conn, ident);
5003 if (!chan) {
5004 /* Could not locate channel, icid is best guess */
5005 l2cap_send_move_chan_cfm_icid(conn, icid);
5006 return;
5007 }
5008
5009 __clear_chan_timer(chan);
5010
5011 if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
5012 if (result == L2CAP_MR_COLLISION) {
5013 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
5014 } else {
5015 /* Cleanup - cancel move */
5016 chan->move_id = chan->local_amp_id;
5017 l2cap_move_done(chan);
5018 }
5019 }
5020
5021 l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
5022
5023 l2cap_chan_unlock(chan);
5024}
5025
5026static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
5027 struct l2cap_cmd_hdr *cmd,
5028 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005029{
5030 struct l2cap_move_chan_rsp *rsp = data;
5031 u16 icid, result;
5032
5033 if (cmd_len != sizeof(*rsp))
5034 return -EPROTO;
5035
5036 icid = le16_to_cpu(rsp->icid);
5037 result = le16_to_cpu(rsp->result);
5038
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005039 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005040
Mat Martineau5b155ef2012-10-23 15:24:14 -07005041 if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND)
5042 l2cap_move_continue(conn, icid, result);
5043 else
5044 l2cap_move_fail(conn, cmd->ident, icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005045
5046 return 0;
5047}
5048
Mat Martineau5f3847a2012-10-23 15:24:12 -07005049static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
5050 struct l2cap_cmd_hdr *cmd,
5051 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005052{
5053 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07005054 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005055 u16 icid, result;
5056
5057 if (cmd_len != sizeof(*cfm))
5058 return -EPROTO;
5059
5060 icid = le16_to_cpu(cfm->icid);
5061 result = le16_to_cpu(cfm->result);
5062
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005063 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005064
Mat Martineau5f3847a2012-10-23 15:24:12 -07005065 chan = l2cap_get_chan_by_dcid(conn, icid);
5066 if (!chan) {
5067 /* Spec requires a response even if the icid was not found */
5068 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5069 return 0;
5070 }
5071
5072 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
5073 if (result == L2CAP_MC_CONFIRMED) {
5074 chan->local_amp_id = chan->move_id;
5075 if (!chan->local_amp_id)
5076 __release_logical_link(chan);
5077 } else {
5078 chan->move_id = chan->local_amp_id;
5079 }
5080
5081 l2cap_move_done(chan);
5082 }
5083
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005084 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
5085
Mat Martineau5f3847a2012-10-23 15:24:12 -07005086 l2cap_chan_unlock(chan);
5087
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005088 return 0;
5089}
5090
5091static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005092 struct l2cap_cmd_hdr *cmd,
5093 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005094{
5095 struct l2cap_move_chan_cfm_rsp *rsp = data;
Mat Martineau3fd71a02012-10-23 15:24:16 -07005096 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005097 u16 icid;
5098
5099 if (cmd_len != sizeof(*rsp))
5100 return -EPROTO;
5101
5102 icid = le16_to_cpu(rsp->icid);
5103
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03005104 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005105
Mat Martineau3fd71a02012-10-23 15:24:16 -07005106 chan = l2cap_get_chan_by_scid(conn, icid);
5107 if (!chan)
5108 return 0;
5109
5110 __clear_chan_timer(chan);
5111
5112 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
5113 chan->local_amp_id = chan->move_id;
5114
5115 if (!chan->local_amp_id && chan->hs_hchan)
5116 __release_logical_link(chan);
5117
5118 l2cap_move_done(chan);
5119 }
5120
5121 l2cap_chan_unlock(chan);
5122
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005123 return 0;
5124}
5125
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005126static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005127 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02005128{
5129 u16 max_latency;
5130
5131 if (min > max || min < 6 || max > 3200)
5132 return -EINVAL;
5133
5134 if (to_multiplier < 10 || to_multiplier > 3200)
5135 return -EINVAL;
5136
5137 if (max >= to_multiplier * 8)
5138 return -EINVAL;
5139
5140 max_latency = (to_multiplier * 8 / max) - 1;
5141 if (latency > 499 || latency > max_latency)
5142 return -EINVAL;
5143
5144 return 0;
5145}
5146
5147static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005148 struct l2cap_cmd_hdr *cmd,
5149 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02005150{
5151 struct hci_conn *hcon = conn->hcon;
5152 struct l2cap_conn_param_update_req *req;
5153 struct l2cap_conn_param_update_rsp rsp;
5154 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005155 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02005156
5157 if (!(hcon->link_mode & HCI_LM_MASTER))
5158 return -EINVAL;
5159
5160 cmd_len = __le16_to_cpu(cmd->len);
5161 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
5162 return -EPROTO;
5163
5164 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03005165 min = __le16_to_cpu(req->min);
5166 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02005167 latency = __le16_to_cpu(req->latency);
5168 to_multiplier = __le16_to_cpu(req->to_multiplier);
5169
5170 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 +01005171 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02005172
5173 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005174
5175 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
5176 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005177 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005178 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005179 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02005180
5181 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005182 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02005183
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02005184 if (!err)
5185 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
5186
Claudio Takahaside731152011-02-11 19:28:55 -02005187 return 0;
5188}
5189
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005190static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005191 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5192 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005193{
5194 int err = 0;
5195
5196 switch (cmd->code) {
5197 case L2CAP_COMMAND_REJ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005198 l2cap_command_rej(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005199 break;
5200
5201 case L2CAP_CONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005202 err = l2cap_connect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005203 break;
5204
5205 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03005206 case L2CAP_CREATE_CHAN_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005207 err = l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005208 break;
5209
5210 case L2CAP_CONF_REQ:
5211 err = l2cap_config_req(conn, cmd, cmd_len, data);
5212 break;
5213
5214 case L2CAP_CONF_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005215 err = l2cap_config_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005216 break;
5217
5218 case L2CAP_DISCONN_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005219 err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005220 break;
5221
5222 case L2CAP_DISCONN_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005223 err = l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005224 break;
5225
5226 case L2CAP_ECHO_REQ:
5227 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
5228 break;
5229
5230 case L2CAP_ECHO_RSP:
5231 break;
5232
5233 case L2CAP_INFO_REQ:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005234 err = l2cap_information_req(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005235 break;
5236
5237 case L2CAP_INFO_RSP:
Johan Hedbergcb3b3152013-05-28 13:46:30 +03005238 err = l2cap_information_rsp(conn, cmd, cmd_len, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005239 break;
5240
Mat Martineauf94ff6f2011-11-02 16:18:32 -07005241 case L2CAP_CREATE_CHAN_REQ:
5242 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
5243 break;
5244
Mat Martineau8d5a04a2011-11-02 16:18:35 -07005245 case L2CAP_MOVE_CHAN_REQ:
5246 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
5247 break;
5248
5249 case L2CAP_MOVE_CHAN_RSP:
5250 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
5251 break;
5252
5253 case L2CAP_MOVE_CHAN_CFM:
5254 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
5255 break;
5256
5257 case L2CAP_MOVE_CHAN_CFM_RSP:
5258 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
5259 break;
5260
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005261 default:
5262 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
5263 err = -EINVAL;
5264 break;
5265 }
5266
5267 return err;
5268}
5269
5270static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005271 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005272{
5273 switch (cmd->code) {
5274 case L2CAP_COMMAND_REJ:
5275 return 0;
5276
5277 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02005278 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005279
5280 case L2CAP_CONN_PARAM_UPDATE_RSP:
5281 return 0;
5282
5283 default:
5284 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5285 return -EINVAL;
5286 }
5287}
5288
Johan Hedbergc5623552013-04-29 19:35:33 +03005289static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5290 struct sk_buff *skb)
5291{
5292 u8 *data = skb->data;
5293 int len = skb->len;
5294 struct l2cap_cmd_hdr cmd;
5295 int err;
5296
5297 l2cap_raw_recv(conn, skb);
5298
5299 while (len >= L2CAP_CMD_HDR_SIZE) {
5300 u16 cmd_len;
5301 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5302 data += L2CAP_CMD_HDR_SIZE;
5303 len -= L2CAP_CMD_HDR_SIZE;
5304
5305 cmd_len = le16_to_cpu(cmd.len);
5306
5307 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5308 cmd.ident);
5309
5310 if (cmd_len > len || !cmd.ident) {
5311 BT_DBG("corrupted command");
5312 break;
5313 }
5314
5315 err = l2cap_le_sig_cmd(conn, &cmd, data);
5316 if (err) {
5317 struct l2cap_cmd_rej_unk rej;
5318
5319 BT_ERR("Wrong link type (%d)", err);
5320
5321 /* FIXME: Map err to a valid reason */
5322 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
5323 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5324 sizeof(rej), &rej);
5325 }
5326
5327 data += cmd_len;
5328 len -= cmd_len;
5329 }
5330
5331 kfree_skb(skb);
5332}
5333
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005334static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005335 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005336{
5337 u8 *data = skb->data;
5338 int len = skb->len;
5339 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005340 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005341
5342 l2cap_raw_recv(conn, skb);
5343
5344 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07005345 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005346 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5347 data += L2CAP_CMD_HDR_SIZE;
5348 len -= L2CAP_CMD_HDR_SIZE;
5349
Al Viro88219a02007-07-29 00:17:25 -07005350 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005351
Gustavo Padovan2d792812012-10-06 10:07:01 +01005352 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5353 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005354
Al Viro88219a02007-07-29 00:17:25 -07005355 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005356 BT_DBG("corrupted command");
5357 break;
5358 }
5359
Johan Hedbergc5623552013-04-29 19:35:33 +03005360 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005361 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03005362 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03005363
5364 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005365
5366 /* FIXME: Map err to a valid reason */
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03005367 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01005368 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5369 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005370 }
5371
Al Viro88219a02007-07-29 00:17:25 -07005372 data += cmd_len;
5373 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005374 }
5375
5376 kfree_skb(skb);
5377}
5378
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005379static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005380{
5381 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03005382 int hdr_size;
5383
5384 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5385 hdr_size = L2CAP_EXT_HDR_SIZE;
5386 else
5387 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005388
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005389 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005390 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005391 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
5392 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
5393
5394 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03005395 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03005396 }
5397 return 0;
5398}
5399
Mat Martineau6ea00482012-05-17 20:53:52 -07005400static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005401{
Mat Martineaue31f7632012-05-17 20:53:41 -07005402 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005403
Mat Martineaue31f7632012-05-17 20:53:41 -07005404 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005405
Mat Martineaue31f7632012-05-17 20:53:41 -07005406 memset(&control, 0, sizeof(control));
5407 control.sframe = 1;
5408 control.final = 1;
5409 control.reqseq = chan->buffer_seq;
5410 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005411
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005412 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07005413 control.super = L2CAP_SUPER_RNR;
5414 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005415 }
5416
Mat Martineaue31f7632012-05-17 20:53:41 -07005417 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5418 chan->unacked_frames > 0)
5419 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005420
Mat Martineaue31f7632012-05-17 20:53:41 -07005421 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03005422 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005423
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03005424 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07005425 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5426 /* F-bit wasn't sent in an s-frame or i-frame yet, so
5427 * send it now.
5428 */
5429 control.super = L2CAP_SUPER_RR;
5430 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03005431 }
5432}
5433
Gustavo Padovan2d792812012-10-06 10:07:01 +01005434static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
5435 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005436{
Mat Martineau84084a32011-07-22 14:54:00 -07005437 /* skb->len reflects data in skb as well as all fragments
5438 * skb->data_len reflects only data in fragments
5439 */
5440 if (!skb_has_frag_list(skb))
5441 skb_shinfo(skb)->frag_list = new_frag;
5442
5443 new_frag->next = NULL;
5444
5445 (*last_frag)->next = new_frag;
5446 *last_frag = new_frag;
5447
5448 skb->len += new_frag->len;
5449 skb->data_len += new_frag->len;
5450 skb->truesize += new_frag->truesize;
5451}
5452
Mat Martineau4b51dae92012-05-17 20:53:37 -07005453static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
5454 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07005455{
5456 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005457
Mat Martineau4b51dae92012-05-17 20:53:37 -07005458 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005459 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07005460 if (chan->sdu)
5461 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005462
Gustavo Padovan80b98022012-05-27 22:27:51 -03005463 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07005464 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005465
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005466 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07005467 if (chan->sdu)
5468 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005469
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005470 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005471 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005472
Mat Martineau84084a32011-07-22 14:54:00 -07005473 if (chan->sdu_len > chan->imtu) {
5474 err = -EMSGSIZE;
5475 break;
5476 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005477
Mat Martineau84084a32011-07-22 14:54:00 -07005478 if (skb->len >= chan->sdu_len)
5479 break;
5480
5481 chan->sdu = skb;
5482 chan->sdu_last_frag = skb;
5483
5484 skb = NULL;
5485 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005486 break;
5487
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005488 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005489 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005490 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005491
Mat Martineau84084a32011-07-22 14:54:00 -07005492 append_skb_frag(chan->sdu, skb,
5493 &chan->sdu_last_frag);
5494 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005495
Mat Martineau84084a32011-07-22 14:54:00 -07005496 if (chan->sdu->len >= chan->sdu_len)
5497 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005498
Mat Martineau84084a32011-07-22 14:54:00 -07005499 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005500 break;
5501
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03005502 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03005503 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07005504 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005505
Mat Martineau84084a32011-07-22 14:54:00 -07005506 append_skb_frag(chan->sdu, skb,
5507 &chan->sdu_last_frag);
5508 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005509
Mat Martineau84084a32011-07-22 14:54:00 -07005510 if (chan->sdu->len != chan->sdu_len)
5511 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005512
Gustavo Padovan80b98022012-05-27 22:27:51 -03005513 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03005514
Mat Martineau84084a32011-07-22 14:54:00 -07005515 if (!err) {
5516 /* Reassembly complete */
5517 chan->sdu = NULL;
5518 chan->sdu_last_frag = NULL;
5519 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005520 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005521 break;
5522 }
5523
Mat Martineau84084a32011-07-22 14:54:00 -07005524 if (err) {
5525 kfree_skb(skb);
5526 kfree_skb(chan->sdu);
5527 chan->sdu = NULL;
5528 chan->sdu_last_frag = NULL;
5529 chan->sdu_len = 0;
5530 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005531
Mat Martineau84084a32011-07-22 14:54:00 -07005532 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03005533}
5534
Mat Martineau32b32732012-10-23 15:24:11 -07005535static int l2cap_resegment(struct l2cap_chan *chan)
5536{
5537 /* Placeholder */
5538 return 0;
5539}
5540
Mat Martineaue3281402011-07-07 09:39:02 -07005541void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03005542{
Mat Martineau61aa4f52012-05-17 20:53:40 -07005543 u8 event;
5544
5545 if (chan->mode != L2CAP_MODE_ERTM)
5546 return;
5547
5548 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03005549 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03005550}
5551
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005552static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5553{
Mat Martineau63838722012-05-17 20:53:45 -07005554 int err = 0;
5555 /* Pass sequential frames to l2cap_reassemble_sdu()
5556 * until a gap is encountered.
5557 */
5558
5559 BT_DBG("chan %p", chan);
5560
5561 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5562 struct sk_buff *skb;
5563 BT_DBG("Searching for skb with txseq %d (queue len %d)",
5564 chan->buffer_seq, skb_queue_len(&chan->srej_q));
5565
5566 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
5567
5568 if (!skb)
5569 break;
5570
5571 skb_unlink(skb, &chan->srej_q);
5572 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5573 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
5574 if (err)
5575 break;
5576 }
5577
5578 if (skb_queue_empty(&chan->srej_q)) {
5579 chan->rx_state = L2CAP_RX_STATE_RECV;
5580 l2cap_send_ack(chan);
5581 }
5582
5583 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005584}
5585
5586static void l2cap_handle_srej(struct l2cap_chan *chan,
5587 struct l2cap_ctrl *control)
5588{
Mat Martineauf80842a2012-05-17 20:53:46 -07005589 struct sk_buff *skb;
5590
5591 BT_DBG("chan %p, control %p", chan, control);
5592
5593 if (control->reqseq == chan->next_tx_seq) {
5594 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005595 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005596 return;
5597 }
5598
5599 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5600
5601 if (skb == NULL) {
5602 BT_DBG("Seq %d not available for retransmission",
5603 control->reqseq);
5604 return;
5605 }
5606
5607 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5608 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005609 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineauf80842a2012-05-17 20:53:46 -07005610 return;
5611 }
5612
5613 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5614
5615 if (control->poll) {
5616 l2cap_pass_to_tx(chan, control);
5617
5618 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5619 l2cap_retransmit(chan, control);
5620 l2cap_ertm_send(chan);
5621
5622 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5623 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5624 chan->srej_save_reqseq = control->reqseq;
5625 }
5626 } else {
5627 l2cap_pass_to_tx_fbit(chan, control);
5628
5629 if (control->final) {
5630 if (chan->srej_save_reqseq != control->reqseq ||
5631 !test_and_clear_bit(CONN_SREJ_ACT,
5632 &chan->conn_state))
5633 l2cap_retransmit(chan, control);
5634 } else {
5635 l2cap_retransmit(chan, control);
5636 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5637 set_bit(CONN_SREJ_ACT, &chan->conn_state);
5638 chan->srej_save_reqseq = control->reqseq;
5639 }
5640 }
5641 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005642}
5643
5644static void l2cap_handle_rej(struct l2cap_chan *chan,
5645 struct l2cap_ctrl *control)
5646{
Mat Martineaufcd289d2012-05-17 20:53:47 -07005647 struct sk_buff *skb;
5648
5649 BT_DBG("chan %p, control %p", chan, control);
5650
5651 if (control->reqseq == chan->next_tx_seq) {
5652 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005653 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005654 return;
5655 }
5656
5657 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5658
5659 if (chan->max_tx && skb &&
5660 bt_cb(skb)->control.retries >= chan->max_tx) {
5661 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005662 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaufcd289d2012-05-17 20:53:47 -07005663 return;
5664 }
5665
5666 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5667
5668 l2cap_pass_to_tx(chan, control);
5669
5670 if (control->final) {
5671 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5672 l2cap_retransmit_all(chan, control);
5673 } else {
5674 l2cap_retransmit_all(chan, control);
5675 l2cap_ertm_send(chan);
5676 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5677 set_bit(CONN_REJ_ACT, &chan->conn_state);
5678 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005679}
5680
Mat Martineau4b51dae92012-05-17 20:53:37 -07005681static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
5682{
5683 BT_DBG("chan %p, txseq %d", chan, txseq);
5684
5685 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
5686 chan->expected_tx_seq);
5687
5688 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
5689 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01005690 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005691 /* See notes below regarding "double poll" and
5692 * invalid packets.
5693 */
5694 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5695 BT_DBG("Invalid/Ignore - after SREJ");
5696 return L2CAP_TXSEQ_INVALID_IGNORE;
5697 } else {
5698 BT_DBG("Invalid - in window after SREJ sent");
5699 return L2CAP_TXSEQ_INVALID;
5700 }
5701 }
5702
5703 if (chan->srej_list.head == txseq) {
5704 BT_DBG("Expected SREJ");
5705 return L2CAP_TXSEQ_EXPECTED_SREJ;
5706 }
5707
5708 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
5709 BT_DBG("Duplicate SREJ - txseq already stored");
5710 return L2CAP_TXSEQ_DUPLICATE_SREJ;
5711 }
5712
5713 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
5714 BT_DBG("Unexpected SREJ - not requested");
5715 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
5716 }
5717 }
5718
5719 if (chan->expected_tx_seq == txseq) {
5720 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
5721 chan->tx_win) {
5722 BT_DBG("Invalid - txseq outside tx window");
5723 return L2CAP_TXSEQ_INVALID;
5724 } else {
5725 BT_DBG("Expected");
5726 return L2CAP_TXSEQ_EXPECTED;
5727 }
5728 }
5729
5730 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01005731 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07005732 BT_DBG("Duplicate - expected_tx_seq later than txseq");
5733 return L2CAP_TXSEQ_DUPLICATE;
5734 }
5735
5736 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
5737 /* A source of invalid packets is a "double poll" condition,
5738 * where delays cause us to send multiple poll packets. If
5739 * the remote stack receives and processes both polls,
5740 * sequence numbers can wrap around in such a way that a
5741 * resent frame has a sequence number that looks like new data
5742 * with a sequence gap. This would trigger an erroneous SREJ
5743 * request.
5744 *
5745 * Fortunately, this is impossible with a tx window that's
5746 * less than half of the maximum sequence number, which allows
5747 * invalid frames to be safely ignored.
5748 *
5749 * With tx window sizes greater than half of the tx window
5750 * maximum, the frame is invalid and cannot be ignored. This
5751 * causes a disconnect.
5752 */
5753
5754 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
5755 BT_DBG("Invalid/Ignore - txseq outside tx window");
5756 return L2CAP_TXSEQ_INVALID_IGNORE;
5757 } else {
5758 BT_DBG("Invalid - txseq outside tx window");
5759 return L2CAP_TXSEQ_INVALID;
5760 }
5761 } else {
5762 BT_DBG("Unexpected - txseq indicates missing frames");
5763 return L2CAP_TXSEQ_UNEXPECTED;
5764 }
5765}
5766
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005767static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5768 struct l2cap_ctrl *control,
5769 struct sk_buff *skb, u8 event)
5770{
5771 int err = 0;
5772 bool skb_in_use = 0;
5773
5774 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5775 event);
5776
5777 switch (event) {
5778 case L2CAP_EV_RECV_IFRAME:
5779 switch (l2cap_classify_txseq(chan, control->txseq)) {
5780 case L2CAP_TXSEQ_EXPECTED:
5781 l2cap_pass_to_tx(chan, control);
5782
5783 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5784 BT_DBG("Busy, discarding expected seq %d",
5785 control->txseq);
5786 break;
5787 }
5788
5789 chan->expected_tx_seq = __next_seq(chan,
5790 control->txseq);
5791
5792 chan->buffer_seq = chan->expected_tx_seq;
5793 skb_in_use = 1;
5794
5795 err = l2cap_reassemble_sdu(chan, skb, control);
5796 if (err)
5797 break;
5798
5799 if (control->final) {
5800 if (!test_and_clear_bit(CONN_REJ_ACT,
5801 &chan->conn_state)) {
5802 control->final = 0;
5803 l2cap_retransmit_all(chan, control);
5804 l2cap_ertm_send(chan);
5805 }
5806 }
5807
5808 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5809 l2cap_send_ack(chan);
5810 break;
5811 case L2CAP_TXSEQ_UNEXPECTED:
5812 l2cap_pass_to_tx(chan, control);
5813
5814 /* Can't issue SREJ frames in the local busy state.
5815 * Drop this frame, it will be seen as missing
5816 * when local busy is exited.
5817 */
5818 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5819 BT_DBG("Busy, discarding unexpected seq %d",
5820 control->txseq);
5821 break;
5822 }
5823
5824 /* There was a gap in the sequence, so an SREJ
5825 * must be sent for each missing frame. The
5826 * current frame is stored for later use.
5827 */
5828 skb_queue_tail(&chan->srej_q, skb);
5829 skb_in_use = 1;
5830 BT_DBG("Queued %p (queue len %d)", skb,
5831 skb_queue_len(&chan->srej_q));
5832
5833 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5834 l2cap_seq_list_clear(&chan->srej_list);
5835 l2cap_send_srej(chan, control->txseq);
5836
5837 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5838 break;
5839 case L2CAP_TXSEQ_DUPLICATE:
5840 l2cap_pass_to_tx(chan, control);
5841 break;
5842 case L2CAP_TXSEQ_INVALID_IGNORE:
5843 break;
5844 case L2CAP_TXSEQ_INVALID:
5845 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005846 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005847 break;
5848 }
5849 break;
5850 case L2CAP_EV_RECV_RR:
5851 l2cap_pass_to_tx(chan, control);
5852 if (control->final) {
5853 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5854
Mat Martineaue6a3ee62012-10-23 15:24:22 -07005855 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) &&
5856 !__chan_is_moving(chan)) {
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005857 control->final = 0;
5858 l2cap_retransmit_all(chan, control);
5859 }
5860
5861 l2cap_ertm_send(chan);
5862 } else if (control->poll) {
5863 l2cap_send_i_or_rr_or_rnr(chan);
5864 } else {
5865 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5866 &chan->conn_state) &&
5867 chan->unacked_frames)
5868 __set_retrans_timer(chan);
5869
5870 l2cap_ertm_send(chan);
5871 }
5872 break;
5873 case L2CAP_EV_RECV_RNR:
5874 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5875 l2cap_pass_to_tx(chan, control);
5876 if (control && control->poll) {
5877 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5878 l2cap_send_rr_or_rnr(chan, 0);
5879 }
5880 __clear_retrans_timer(chan);
5881 l2cap_seq_list_clear(&chan->retrans_list);
5882 break;
5883 case L2CAP_EV_RECV_REJ:
5884 l2cap_handle_rej(chan, control);
5885 break;
5886 case L2CAP_EV_RECV_SREJ:
5887 l2cap_handle_srej(chan, control);
5888 break;
5889 default:
5890 break;
5891 }
5892
5893 if (skb && !skb_in_use) {
5894 BT_DBG("Freeing %p", skb);
5895 kfree_skb(skb);
5896 }
5897
5898 return err;
5899}
5900
5901static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5902 struct l2cap_ctrl *control,
5903 struct sk_buff *skb, u8 event)
5904{
5905 int err = 0;
5906 u16 txseq = control->txseq;
5907 bool skb_in_use = 0;
5908
5909 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5910 event);
5911
5912 switch (event) {
5913 case L2CAP_EV_RECV_IFRAME:
5914 switch (l2cap_classify_txseq(chan, txseq)) {
5915 case L2CAP_TXSEQ_EXPECTED:
5916 /* Keep frame for reassembly later */
5917 l2cap_pass_to_tx(chan, control);
5918 skb_queue_tail(&chan->srej_q, skb);
5919 skb_in_use = 1;
5920 BT_DBG("Queued %p (queue len %d)", skb,
5921 skb_queue_len(&chan->srej_q));
5922
5923 chan->expected_tx_seq = __next_seq(chan, txseq);
5924 break;
5925 case L2CAP_TXSEQ_EXPECTED_SREJ:
5926 l2cap_seq_list_pop(&chan->srej_list);
5927
5928 l2cap_pass_to_tx(chan, control);
5929 skb_queue_tail(&chan->srej_q, skb);
5930 skb_in_use = 1;
5931 BT_DBG("Queued %p (queue len %d)", skb,
5932 skb_queue_len(&chan->srej_q));
5933
5934 err = l2cap_rx_queued_iframes(chan);
5935 if (err)
5936 break;
5937
5938 break;
5939 case L2CAP_TXSEQ_UNEXPECTED:
5940 /* Got a frame that can't be reassembled yet.
5941 * Save it for later, and send SREJs to cover
5942 * the missing frames.
5943 */
5944 skb_queue_tail(&chan->srej_q, skb);
5945 skb_in_use = 1;
5946 BT_DBG("Queued %p (queue len %d)", skb,
5947 skb_queue_len(&chan->srej_q));
5948
5949 l2cap_pass_to_tx(chan, control);
5950 l2cap_send_srej(chan, control->txseq);
5951 break;
5952 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
5953 /* This frame was requested with an SREJ, but
5954 * some expected retransmitted frames are
5955 * missing. Request retransmission of missing
5956 * SREJ'd frames.
5957 */
5958 skb_queue_tail(&chan->srej_q, skb);
5959 skb_in_use = 1;
5960 BT_DBG("Queued %p (queue len %d)", skb,
5961 skb_queue_len(&chan->srej_q));
5962
5963 l2cap_pass_to_tx(chan, control);
5964 l2cap_send_srej_list(chan, control->txseq);
5965 break;
5966 case L2CAP_TXSEQ_DUPLICATE_SREJ:
5967 /* We've already queued this frame. Drop this copy. */
5968 l2cap_pass_to_tx(chan, control);
5969 break;
5970 case L2CAP_TXSEQ_DUPLICATE:
5971 /* Expecting a later sequence number, so this frame
5972 * was already received. Ignore it completely.
5973 */
5974 break;
5975 case L2CAP_TXSEQ_INVALID_IGNORE:
5976 break;
5977 case L2CAP_TXSEQ_INVALID:
5978 default:
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02005979 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005980 break;
5981 }
5982 break;
5983 case L2CAP_EV_RECV_RR:
5984 l2cap_pass_to_tx(chan, control);
5985 if (control->final) {
5986 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5987
5988 if (!test_and_clear_bit(CONN_REJ_ACT,
5989 &chan->conn_state)) {
5990 control->final = 0;
5991 l2cap_retransmit_all(chan, control);
5992 }
5993
5994 l2cap_ertm_send(chan);
5995 } else if (control->poll) {
5996 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5997 &chan->conn_state) &&
5998 chan->unacked_frames) {
5999 __set_retrans_timer(chan);
6000 }
6001
6002 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6003 l2cap_send_srej_tail(chan);
6004 } else {
6005 if (test_and_clear_bit(CONN_REMOTE_BUSY,
6006 &chan->conn_state) &&
6007 chan->unacked_frames)
6008 __set_retrans_timer(chan);
6009
6010 l2cap_send_ack(chan);
6011 }
6012 break;
6013 case L2CAP_EV_RECV_RNR:
6014 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6015 l2cap_pass_to_tx(chan, control);
6016 if (control->poll) {
6017 l2cap_send_srej_tail(chan);
6018 } else {
6019 struct l2cap_ctrl rr_control;
6020 memset(&rr_control, 0, sizeof(rr_control));
6021 rr_control.sframe = 1;
6022 rr_control.super = L2CAP_SUPER_RR;
6023 rr_control.reqseq = chan->buffer_seq;
6024 l2cap_send_sframe(chan, &rr_control);
6025 }
6026
6027 break;
6028 case L2CAP_EV_RECV_REJ:
6029 l2cap_handle_rej(chan, control);
6030 break;
6031 case L2CAP_EV_RECV_SREJ:
6032 l2cap_handle_srej(chan, control);
6033 break;
6034 }
6035
6036 if (skb && !skb_in_use) {
6037 BT_DBG("Freeing %p", skb);
6038 kfree_skb(skb);
6039 }
6040
6041 return err;
6042}
6043
Mat Martineau32b32732012-10-23 15:24:11 -07006044static int l2cap_finish_move(struct l2cap_chan *chan)
6045{
6046 BT_DBG("chan %p", chan);
6047
6048 chan->rx_state = L2CAP_RX_STATE_RECV;
6049
6050 if (chan->hs_hcon)
6051 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6052 else
6053 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6054
6055 return l2cap_resegment(chan);
6056}
6057
6058static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
6059 struct l2cap_ctrl *control,
6060 struct sk_buff *skb, u8 event)
6061{
6062 int err;
6063
6064 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6065 event);
6066
6067 if (!control->poll)
6068 return -EPROTO;
6069
6070 l2cap_process_reqseq(chan, control->reqseq);
6071
6072 if (!skb_queue_empty(&chan->tx_q))
6073 chan->tx_send_head = skb_peek(&chan->tx_q);
6074 else
6075 chan->tx_send_head = NULL;
6076
6077 /* Rewind next_tx_seq to the point expected
6078 * by the receiver.
6079 */
6080 chan->next_tx_seq = control->reqseq;
6081 chan->unacked_frames = 0;
6082
6083 err = l2cap_finish_move(chan);
6084 if (err)
6085 return err;
6086
6087 set_bit(CONN_SEND_FBIT, &chan->conn_state);
6088 l2cap_send_i_or_rr_or_rnr(chan);
6089
6090 if (event == L2CAP_EV_RECV_IFRAME)
6091 return -EPROTO;
6092
6093 return l2cap_rx_state_recv(chan, control, NULL, event);
6094}
6095
6096static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
6097 struct l2cap_ctrl *control,
6098 struct sk_buff *skb, u8 event)
6099{
6100 int err;
6101
6102 if (!control->final)
6103 return -EPROTO;
6104
6105 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6106
6107 chan->rx_state = L2CAP_RX_STATE_RECV;
6108 l2cap_process_reqseq(chan, control->reqseq);
6109
6110 if (!skb_queue_empty(&chan->tx_q))
6111 chan->tx_send_head = skb_peek(&chan->tx_q);
6112 else
6113 chan->tx_send_head = NULL;
6114
6115 /* Rewind next_tx_seq to the point expected
6116 * by the receiver.
6117 */
6118 chan->next_tx_seq = control->reqseq;
6119 chan->unacked_frames = 0;
6120
6121 if (chan->hs_hcon)
6122 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
6123 else
6124 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
6125
6126 err = l2cap_resegment(chan);
6127
6128 if (!err)
6129 err = l2cap_rx_state_recv(chan, control, skb, event);
6130
6131 return err;
6132}
6133
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006134static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6135{
6136 /* Make sure reqseq is for a packet that has been sent but not acked */
6137 u16 unacked;
6138
6139 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6140 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6141}
6142
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006143static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6144 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006145{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006146 int err = 0;
6147
6148 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6149 control, skb, event, chan->rx_state);
6150
6151 if (__valid_reqseq(chan, control->reqseq)) {
6152 switch (chan->rx_state) {
6153 case L2CAP_RX_STATE_RECV:
6154 err = l2cap_rx_state_recv(chan, control, skb, event);
6155 break;
6156 case L2CAP_RX_STATE_SREJ_SENT:
6157 err = l2cap_rx_state_srej_sent(chan, control, skb,
6158 event);
6159 break;
Mat Martineau32b32732012-10-23 15:24:11 -07006160 case L2CAP_RX_STATE_WAIT_P:
6161 err = l2cap_rx_state_wait_p(chan, control, skb, event);
6162 break;
6163 case L2CAP_RX_STATE_WAIT_F:
6164 err = l2cap_rx_state_wait_f(chan, control, skb, event);
6165 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006166 default:
6167 /* shut it down */
6168 break;
6169 }
6170 } else {
6171 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6172 control->reqseq, chan->next_tx_seq,
6173 chan->expected_ack_seq);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006174 l2cap_send_disconn_req(chan, ECONNRESET);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07006175 }
6176
6177 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006178}
6179
6180static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6181 struct sk_buff *skb)
6182{
Mat Martineau4b51dae92012-05-17 20:53:37 -07006183 int err = 0;
6184
6185 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
6186 chan->rx_state);
6187
6188 if (l2cap_classify_txseq(chan, control->txseq) ==
6189 L2CAP_TXSEQ_EXPECTED) {
6190 l2cap_pass_to_tx(chan, control);
6191
6192 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
6193 __next_seq(chan, chan->buffer_seq));
6194
6195 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
6196
6197 l2cap_reassemble_sdu(chan, skb, control);
6198 } else {
6199 if (chan->sdu) {
6200 kfree_skb(chan->sdu);
6201 chan->sdu = NULL;
6202 }
6203 chan->sdu_last_frag = NULL;
6204 chan->sdu_len = 0;
6205
6206 if (skb) {
6207 BT_DBG("Freeing %p", skb);
6208 kfree_skb(skb);
6209 }
6210 }
6211
6212 chan->last_acked_seq = control->txseq;
6213 chan->expected_tx_seq = __next_seq(chan, control->txseq);
6214
6215 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006216}
6217
6218static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6219{
6220 struct l2cap_ctrl *control = &bt_cb(skb)->control;
6221 u16 len;
6222 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006223
Mat Martineaub76bbd62012-04-11 10:48:43 -07006224 __unpack_control(chan, skb);
6225
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006226 len = skb->len;
6227
6228 /*
6229 * We can just drop the corrupted I-frame here.
6230 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006231 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006232 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006233 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006234 goto drop;
6235
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006236 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006237 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006238
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006239 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03006240 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006241
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03006242 if (len > chan->mps) {
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006243 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006244 goto drop;
6245 }
6246
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006247 if (!control->sframe) {
6248 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006249
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006250 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6251 control->sar, control->reqseq, control->final,
6252 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03006253
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006254 /* Validate F-bit - F=0 always valid, F=1 only
6255 * valid in TX WAIT_F
6256 */
6257 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006258 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006259
6260 if (chan->mode != L2CAP_MODE_STREAMING) {
6261 event = L2CAP_EV_RECV_IFRAME;
6262 err = l2cap_rx(chan, control, skb, event);
6263 } else {
6264 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006265 }
6266
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006267 if (err)
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006268 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006269 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006270 const u8 rx_func_to_event[4] = {
6271 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6272 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6273 };
6274
6275 /* Only I-frames are expected in streaming mode */
6276 if (chan->mode == L2CAP_MODE_STREAMING)
6277 goto drop;
6278
6279 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6280 control->reqseq, control->final, control->poll,
6281 control->super);
6282
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006283 if (len != 0) {
Andrei Emeltchenko1bb166e2012-11-20 17:16:21 +02006284 BT_ERR("Trailing bytes: %d in sframe", len);
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006285 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006286 goto drop;
6287 }
6288
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006289 /* Validate F and P bits */
6290 if (control->final && (control->poll ||
6291 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6292 goto drop;
6293
6294 event = rx_func_to_event[control->super];
6295 if (l2cap_rx(chan, control, skb, event))
Andrei Emeltchenko5e4e3972012-11-28 17:59:39 +02006296 l2cap_send_disconn_req(chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03006297 }
6298
6299 return 0;
6300
6301drop:
6302 kfree_skb(skb);
6303 return 0;
6304}
6305
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006306static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
6307 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006308{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006309 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006310
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03006311 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006312 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006313 if (cid == L2CAP_CID_A2MP) {
6314 chan = a2mp_channel_create(conn, skb);
6315 if (!chan) {
6316 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006317 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006318 }
6319
6320 l2cap_chan_lock(chan);
6321 } else {
6322 BT_DBG("unknown cid 0x%4.4x", cid);
6323 /* Drop packet and return */
6324 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03006325 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03006326 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006327 }
6328
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03006329 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006330
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006331 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006332 goto drop;
6333
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006334 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006335 case L2CAP_MODE_BASIC:
6336 /* If socket recv buffers overflows we drop data here
6337 * which is *bad* because L2CAP has to be reliable.
6338 * But we don't have any other choice. L2CAP doesn't
6339 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006340
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006341 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006342 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006343
Gustavo Padovan80b98022012-05-27 22:27:51 -03006344 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006345 goto done;
6346 break;
6347
6348 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006349 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07006350 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03006351 goto done;
6352
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006353 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03006354 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006355 break;
6356 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006357
6358drop:
6359 kfree_skb(skb);
6360
6361done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006362 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006363}
6364
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006365static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
6366 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006367{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006368 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006369
Ido Yarivc2287682012-04-20 15:46:07 -03006370 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006371 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006372 goto drop;
6373
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006374 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006375
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006376 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006377 goto drop;
6378
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006379 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006380 goto drop;
6381
Gustavo Padovan80b98022012-05-27 22:27:51 -03006382 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03006383 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006384
6385drop:
6386 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006387}
6388
Marcel Holtmann72f78352013-04-23 00:59:00 -07006389static void l2cap_att_channel(struct l2cap_conn *conn,
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006390 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006391{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006392 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006393
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006394 chan = l2cap_global_chan_by_scid(0, L2CAP_CID_ATT,
Marcel Holtmann72f78352013-04-23 00:59:00 -07006395 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006396 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006397 goto drop;
6398
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02006399 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006400
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006401 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006402 goto drop;
6403
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03006404 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006405 goto drop;
6406
Gustavo Padovan80b98022012-05-27 22:27:51 -03006407 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03006408 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006409
6410drop:
6411 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006412}
6413
Linus Torvalds1da177e2005-04-16 15:20:36 -07006414static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6415{
6416 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07006417 u16 cid, len;
6418 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006419
6420 skb_pull(skb, L2CAP_HDR_SIZE);
6421 cid = __le16_to_cpu(lh->cid);
6422 len = __le16_to_cpu(lh->len);
6423
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03006424 if (len != skb->len) {
6425 kfree_skb(skb);
6426 return;
6427 }
6428
Linus Torvalds1da177e2005-04-16 15:20:36 -07006429 BT_DBG("len %d, cid 0x%4.4x", len, cid);
6430
6431 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02006432 case L2CAP_CID_LE_SIGNALING:
Johan Hedbergc5623552013-04-29 19:35:33 +03006433 l2cap_le_sig_channel(conn, skb);
6434 break;
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006435 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006436 l2cap_sig_channel(conn, skb);
6437 break;
6438
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03006439 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02006440 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03006441 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006442 l2cap_conless_channel(conn, psm, skb);
6443 break;
6444
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006445 case L2CAP_CID_ATT:
Marcel Holtmann72f78352013-04-23 00:59:00 -07006446 l2cap_att_channel(conn, skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03006447 break;
6448
Anderson Brigliab501d6a2011-06-07 18:46:31 -03006449 case L2CAP_CID_SMP:
6450 if (smp_sig_channel(conn, skb))
6451 l2cap_conn_del(conn->hcon, EACCES);
6452 break;
6453
Linus Torvalds1da177e2005-04-16 15:20:36 -07006454 default:
6455 l2cap_data_channel(conn, cid, skb);
6456 break;
6457 }
6458}
6459
6460/* ---- L2CAP interface with lower layer (HCI) ---- */
6461
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006462int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006463{
6464 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006465 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006466
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006467 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006468
6469 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006470 read_lock(&chan_list_lock);
6471 list_for_each_entry(c, &chan_list, global_l) {
6472 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006473
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006474 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006475 continue;
6476
6477 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006478 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006479 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006480 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006481 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006482 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
6483 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03006484 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01006485 lm2 |= HCI_LM_MASTER;
6486 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006487 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006488 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006489
6490 return exact ? lm1 : lm2;
6491}
6492
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006493void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006494{
Marcel Holtmann01394182006-07-03 10:02:46 +02006495 struct l2cap_conn *conn;
6496
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03006497 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006498
Linus Torvalds1da177e2005-04-16 15:20:36 -07006499 if (!status) {
Claudio Takahasibaf43252013-04-11 13:55:50 -03006500 conn = l2cap_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006501 if (conn)
6502 l2cap_conn_ready(conn);
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006503 } else {
Joe Perchese1750722011-06-29 18:18:29 -07006504 l2cap_conn_del(hcon, bt_to_errno(status));
Andrei Emeltchenkoba6fc312012-10-31 15:46:26 +02006505 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006506}
6507
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006508int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01006509{
6510 struct l2cap_conn *conn = hcon->l2cap_data;
6511
6512 BT_DBG("hcon %p", hcon);
6513
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006514 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02006515 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01006516 return conn->disc_reason;
6517}
6518
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03006519void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006520{
6521 BT_DBG("hcon %p reason %d", hcon, reason);
6522
Joe Perchese1750722011-06-29 18:18:29 -07006523 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006524}
6525
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006526static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006527{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03006528 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01006529 return;
6530
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006531 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006532 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006533 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006534 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03006535 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006536 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006537 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03006538 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01006539 }
6540}
6541
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006542int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006543{
Marcel Holtmann40be4922008-07-14 20:13:50 +02006544 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03006545 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006546
Marcel Holtmann01394182006-07-03 10:02:46 +02006547 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006548 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02006549
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006550 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006551
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006552 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05306553 if (!status && encrypt)
6554 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02006555 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03006556 }
6557
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006558 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006559
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006560 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006561 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006562
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03006563 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
6564 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006565
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03006566 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
6567 l2cap_chan_unlock(chan);
6568 continue;
6569 }
6570
Johan Hedberg073d1cf2013-04-29 19:35:35 +03006571 if (chan->scid == L2CAP_CID_ATT) {
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006572 if (!status && encrypt) {
6573 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02006574 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006575 }
6576
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006577 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03006578 continue;
6579 }
6580
Andrei Emeltchenko96eff462012-11-15 18:14:53 +02006581 if (!__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006582 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01006583 continue;
6584 }
6585
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006586 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01006587 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03006588 struct sock *sk = chan->sk;
6589
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006590 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03006591 sk->sk_state_change(sk);
6592
Gustavo F. Padovan43434782011-04-12 18:31:57 -03006593 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006594 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02006595 continue;
6596 }
6597
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006598 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006599 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03006600 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006601 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006602 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006603 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03006604 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006605 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006606 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006607 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006608
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006609 lock_sock(sk);
6610
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006611 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03006612 if (test_bit(BT_SK_DEFER_SETUP,
6613 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006614 res = L2CAP_CR_PEND;
6615 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08006616 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006617 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006618 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006619 res = L2CAP_CR_SUCCESS;
6620 stat = L2CAP_CS_NO_INFO;
6621 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006622 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02006623 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08006624 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006625 res = L2CAP_CR_SEC_BLOCK;
6626 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006627 }
6628
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006629 release_sock(sk);
6630
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03006631 rsp.scid = cpu_to_le16(chan->dcid);
6632 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03006633 rsp.result = cpu_to_le16(res);
6634 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03006635 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01006636 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07006637
6638 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
6639 res == L2CAP_CR_SUCCESS) {
6640 char buf[128];
6641 set_bit(CONF_REQ_SENT, &chan->conf_state);
6642 l2cap_send_cmd(conn, l2cap_get_ident(conn),
6643 L2CAP_CONF_REQ,
6644 l2cap_build_conf_req(chan, buf),
6645 buf);
6646 chan->num_conf_req++;
6647 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006648 }
6649
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02006650 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006651 }
6652
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02006653 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02006654
Linus Torvalds1da177e2005-04-16 15:20:36 -07006655 return 0;
6656}
6657
Ulisses Furquim686ebf22011-12-21 10:11:33 -02006658int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006659{
6660 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006661 struct l2cap_hdr *hdr;
6662 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006663
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03006664 /* For AMP controller do not create l2cap conn */
6665 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
6666 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006667
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006668 if (!conn)
Claudio Takahasibaf43252013-04-11 13:55:50 -03006669 conn = l2cap_conn_add(hcon);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02006670
6671 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006672 goto drop;
6673
6674 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
6675
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006676 switch (flags) {
6677 case ACL_START:
6678 case ACL_START_NO_FLUSH:
6679 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006680 if (conn->rx_len) {
6681 BT_ERR("Unexpected start frame (len %d)", skb->len);
6682 kfree_skb(conn->rx_skb);
6683 conn->rx_skb = NULL;
6684 conn->rx_len = 0;
6685 l2cap_conn_unreliable(conn, ECOMM);
6686 }
6687
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03006688 /* Start fragment always begin with Basic L2CAP header */
6689 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006690 BT_ERR("Frame is too short (len %d)", skb->len);
6691 l2cap_conn_unreliable(conn, ECOMM);
6692 goto drop;
6693 }
6694
6695 hdr = (struct l2cap_hdr *) skb->data;
6696 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
6697
6698 if (len == skb->len) {
6699 /* Complete frame received */
6700 l2cap_recv_frame(conn, skb);
6701 return 0;
6702 }
6703
6704 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
6705
6706 if (skb->len > len) {
6707 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006708 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006709 l2cap_conn_unreliable(conn, ECOMM);
6710 goto drop;
6711 }
6712
6713 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03006714 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03006715 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006716 goto drop;
6717
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006718 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006719 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006720 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006721 break;
6722
6723 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006724 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
6725
6726 if (!conn->rx_len) {
6727 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
6728 l2cap_conn_unreliable(conn, ECOMM);
6729 goto drop;
6730 }
6731
6732 if (skb->len > conn->rx_len) {
6733 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01006734 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006735 kfree_skb(conn->rx_skb);
6736 conn->rx_skb = NULL;
6737 conn->rx_len = 0;
6738 l2cap_conn_unreliable(conn, ECOMM);
6739 goto drop;
6740 }
6741
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03006742 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01006743 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006744 conn->rx_len -= skb->len;
6745
6746 if (!conn->rx_len) {
6747 /* Complete frame received */
6748 l2cap_recv_frame(conn, conn->rx_skb);
6749 conn->rx_skb = NULL;
6750 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03006751 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006752 }
6753
6754drop:
6755 kfree_skb(skb);
6756 return 0;
6757}
6758
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006759static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006760{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006761 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006762
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006763 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006764
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03006765 list_for_each_entry(c, &chan_list, global_l) {
6766 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006767
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006768 seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
6769 &bt_sk(sk)->src, &bt_sk(sk)->dst,
6770 c->state, __le16_to_cpu(c->psm),
6771 c->scid, c->dcid, c->imtu, c->omtu,
6772 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006773 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006774
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006775 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006776
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006777 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006778}
6779
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006780static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6781{
6782 return single_open(file, l2cap_debugfs_show, inode->i_private);
6783}
6784
6785static const struct file_operations l2cap_debugfs_fops = {
6786 .open = l2cap_debugfs_open,
6787 .read = seq_read,
6788 .llseek = seq_lseek,
6789 .release = single_release,
6790};
6791
6792static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006793
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006794int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006795{
6796 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006797
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006798 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006799 if (err < 0)
6800 return err;
6801
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006802 if (bt_debugfs) {
Gustavo Padovan2d792812012-10-06 10:07:01 +01006803 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6804 NULL, &l2cap_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006805 if (!l2cap_debugfs)
6806 BT_ERR("Failed to create L2CAP debug file");
6807 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006808
Linus Torvalds1da177e2005-04-16 15:20:36 -07006809 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006810}
6811
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006812void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006813{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006814 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006815 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006816}
6817
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006818module_param(disable_ertm, bool, 0644);
6819MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");