blob: fef0394add18faa4880f005ec4c907022b4357a0 [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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041
Mat Martineaud1de6d42012-05-17 20:53:55 -070042bool disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020043
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070044static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Mat Martineau50a147c2011-11-02 16:18:34 -070045static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070046
Johannes Bergb5ad8b72011-06-01 08:54:45 +020047static LIST_HEAD(chan_list);
48static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
Linus Torvalds1da177e2005-04-16 15:20:36 -070050static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +010051 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030052static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
Gustavo Padovan2d792812012-10-06 10:07:01 +010053 void *data);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -030054static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030055static void l2cap_send_disconn_req(struct l2cap_conn *conn,
Gustavo Padovanc5daa682012-05-16 12:17:10 -030056 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
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300132static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300133{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300134 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300135
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300136 list_for_each_entry(c, &chan_list, global_l) {
137 if (c->sport == psm && !bacmp(&bt_sk(c->sk)->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100138 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300139 }
Szymon Janc250938c2011-11-16 09:32:22 +0100140 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300141}
142
143int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
144{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300145 int err;
146
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200147 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300148
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300149 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300150 err = -EADDRINUSE;
151 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300152 }
153
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300154 if (psm) {
155 chan->psm = psm;
156 chan->sport = psm;
157 err = 0;
158 } else {
159 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300160
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300161 err = -EINVAL;
162 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300163 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300164 chan->psm = cpu_to_le16(p);
165 chan->sport = cpu_to_le16(p);
166 err = 0;
167 break;
168 }
169 }
170
171done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200172 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300173 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300174}
175
176int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
177{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200178 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300179
180 chan->scid = scid;
181
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200182 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300183
184 return 0;
185}
186
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300187static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200188{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300189 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200190
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300191 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300192 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200193 return cid;
194 }
195
196 return 0;
197}
198
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200199static void __l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300200{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200201 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100202 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200203
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300204 chan->state = state;
Gustavo Padovan80b98022012-05-27 22:27:51 -0300205 chan->ops->state_change(chan, state);
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300206}
207
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200208static void l2cap_state_change(struct l2cap_chan *chan, int state)
209{
210 struct sock *sk = chan->sk;
211
212 lock_sock(sk);
213 __l2cap_state_change(chan, state);
214 release_sock(sk);
215}
216
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200217static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err)
218{
219 struct sock *sk = chan->sk;
220
221 sk->sk_err = err;
222}
223
224static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
225{
226 struct sock *sk = chan->sk;
227
228 lock_sock(sk);
229 __l2cap_chan_set_err(chan, err);
230 release_sock(sk);
231}
232
Mat Martineau4239d162012-05-17 20:53:49 -0700233static void __set_retrans_timer(struct l2cap_chan *chan)
234{
235 if (!delayed_work_pending(&chan->monitor_timer) &&
236 chan->retrans_timeout) {
237 l2cap_set_timer(chan, &chan->retrans_timer,
238 msecs_to_jiffies(chan->retrans_timeout));
239 }
240}
241
242static void __set_monitor_timer(struct l2cap_chan *chan)
243{
244 __clear_retrans_timer(chan);
245 if (chan->monitor_timeout) {
246 l2cap_set_timer(chan, &chan->monitor_timer,
247 msecs_to_jiffies(chan->monitor_timeout));
248 }
249}
250
Mat Martineau608bcc62012-05-17 20:53:32 -0700251static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
252 u16 seq)
253{
254 struct sk_buff *skb;
255
256 skb_queue_walk(head, skb) {
257 if (bt_cb(skb)->control.txseq == seq)
258 return skb;
259 }
260
261 return NULL;
262}
263
Mat Martineau3c588192012-04-11 10:48:42 -0700264/* ---- L2CAP sequence number lists ---- */
265
266/* For ERTM, ordered lists of sequence numbers must be tracked for
267 * SREJ requests that are received and for frames that are to be
268 * retransmitted. These seq_list functions implement a singly-linked
269 * list in an array, where membership in the list can also be checked
270 * in constant time. Items can also be added to the tail of the list
271 * and removed from the head in constant time, without further memory
272 * allocs or frees.
273 */
274
275static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
276{
277 size_t alloc_size, i;
278
279 /* Allocated size is a power of 2 to map sequence numbers
280 * (which may be up to 14 bits) in to a smaller array that is
281 * sized for the negotiated ERTM transmit windows.
282 */
283 alloc_size = roundup_pow_of_two(size);
284
285 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
286 if (!seq_list->list)
287 return -ENOMEM;
288
289 seq_list->mask = alloc_size - 1;
290 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
291 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
292 for (i = 0; i < alloc_size; i++)
293 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
294
295 return 0;
296}
297
298static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
299{
300 kfree(seq_list->list);
301}
302
303static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
304 u16 seq)
305{
306 /* Constant-time check for list membership */
307 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
308}
309
310static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
311{
312 u16 mask = seq_list->mask;
313
314 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
315 /* In case someone tries to pop the head of an empty list */
316 return L2CAP_SEQ_LIST_CLEAR;
317 } else if (seq_list->head == seq) {
318 /* Head can be removed in constant time */
319 seq_list->head = seq_list->list[seq & mask];
320 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
321
322 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
323 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
324 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
325 }
326 } else {
327 /* Walk the list to find the sequence number */
328 u16 prev = seq_list->head;
329 while (seq_list->list[prev & mask] != seq) {
330 prev = seq_list->list[prev & mask];
331 if (prev == L2CAP_SEQ_LIST_TAIL)
332 return L2CAP_SEQ_LIST_CLEAR;
333 }
334
335 /* Unlink the number from the list and clear it */
336 seq_list->list[prev & mask] = seq_list->list[seq & mask];
337 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
338 if (seq_list->tail == seq)
339 seq_list->tail = prev;
340 }
341 return seq;
342}
343
344static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
345{
346 /* Remove the head in constant time */
347 return l2cap_seq_list_remove(seq_list, seq_list->head);
348}
349
350static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
351{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300352 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700353
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300354 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
355 return;
356
357 for (i = 0; i <= seq_list->mask; i++)
358 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
359
360 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
361 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700362}
363
364static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
365{
366 u16 mask = seq_list->mask;
367
368 /* All appends happen in constant time */
369
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300370 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
371 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700372
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300373 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
374 seq_list->head = seq;
375 else
376 seq_list->list[seq_list->tail & mask] = seq;
377
378 seq_list->tail = seq;
379 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700380}
381
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300382static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300383{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300384 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100385 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200386 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300387 int reason;
388
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200389 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300390
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200391 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200392 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300393
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300394 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300395 reason = ECONNREFUSED;
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300396 else if (chan->state == BT_CONNECT &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100397 chan->sec_level != BT_SECURITY_SDP)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300398 reason = ECONNREFUSED;
399 else
400 reason = ETIMEDOUT;
401
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300402 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300403
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200404 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300405
Gustavo Padovan80b98022012-05-27 22:27:51 -0300406 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200407 mutex_unlock(&conn->chan_lock);
408
Ulisses Furquim371fd832011-12-21 20:02:36 -0200409 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300410}
411
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300412struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200413{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300414 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200415
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300416 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
417 if (!chan)
418 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200419
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200420 mutex_init(&chan->lock);
421
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200422 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300423 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200424 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300425
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300426 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300427
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300428 chan->state = BT_OPEN;
429
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530430 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300431
Mat Martineau28270112012-05-17 21:14:09 -0700432 /* This flag is cleared in l2cap_chan_ready() */
433 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
434
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300435 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100436
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300437 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200438}
439
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530440static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300441{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530442 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
443
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530444 BT_DBG("chan %p", chan);
445
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200446 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300447 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200448 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300449
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530450 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300451}
452
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530453void l2cap_chan_hold(struct l2cap_chan *c)
454{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530455 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530456
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530457 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530458}
459
460void l2cap_chan_put(struct l2cap_chan *c)
461{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530462 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530463
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530464 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530465}
466
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300467void l2cap_chan_set_defaults(struct l2cap_chan *chan)
468{
469 chan->fcs = L2CAP_FCS_CRC16;
470 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
471 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
472 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700473 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300474 chan->sec_level = BT_SECURITY_LOW;
475
476 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
477}
478
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300479void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200480{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300481 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200482 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200483
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200484 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100485
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300486 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200487
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200488 switch (chan->chan_type) {
489 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300490 if (conn->hcon->type == LE_LINK) {
491 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300492 chan->omtu = L2CAP_DEFAULT_MTU;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300493 chan->scid = L2CAP_CID_LE_DATA;
494 chan->dcid = L2CAP_CID_LE_DATA;
Ville Tervob62f3282011-02-10 22:38:50 -0300495 } else {
496 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300497 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300498 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300499 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200500 break;
501
502 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200503 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300504 chan->scid = L2CAP_CID_CONN_LESS;
505 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300506 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200507 break;
508
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300509 case L2CAP_CHAN_CONN_FIX_A2MP:
510 chan->scid = L2CAP_CID_A2MP;
511 chan->dcid = L2CAP_CID_A2MP;
512 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
513 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
514 break;
515
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200516 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200517 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300518 chan->scid = L2CAP_CID_SIGNALING;
519 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300520 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200521 }
522
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300523 chan->local_id = L2CAP_BESTEFFORT_ID;
524 chan->local_stype = L2CAP_SERV_BESTEFFORT;
525 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
526 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
527 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300528 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300529
Ulisses Furquim371fd832011-12-21 20:02:36 -0200530 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300531
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200532 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200533}
534
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300535void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200536{
537 mutex_lock(&conn->chan_lock);
538 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200539 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200540}
541
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300542void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200543{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300544 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200545
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300546 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200547
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300548 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200549
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900550 if (conn) {
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300551 struct amp_mgr *mgr = conn->hcon->amp_mgr;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300552 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200553 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200554
Ulisses Furquim371fd832011-12-21 20:02:36 -0200555 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300556
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300557 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300558
559 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
560 hci_conn_put(conn->hcon);
Andrei Emeltchenko56f60982012-10-15 11:58:44 +0300561
562 if (mgr && mgr->bredr_chan == chan)
563 mgr->bredr_chan = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200564 }
565
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100566 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200567
Mat Martineau28270112012-05-17 21:14:09 -0700568 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300569 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300570
Gustavo Padovanee556f62012-05-18 20:22:38 -0300571 switch(chan->mode) {
572 case L2CAP_MODE_BASIC:
573 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300574
Gustavo Padovanee556f62012-05-18 20:22:38 -0300575 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300576 __clear_retrans_timer(chan);
577 __clear_monitor_timer(chan);
578 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300579
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300580 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300581
Mat Martineau3c588192012-04-11 10:48:42 -0700582 l2cap_seq_list_free(&chan->srej_list);
583 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300584
585 /* fall through */
586
587 case L2CAP_MODE_STREAMING:
588 skb_queue_purge(&chan->tx_q);
589 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300590 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300591
592 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200593}
594
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300595void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300596{
597 struct l2cap_conn *conn = chan->conn;
598 struct sock *sk = chan->sk;
599
Gustavo Padovan2d792812012-10-06 10:07:01 +0100600 BT_DBG("chan %p state %s sk %p", chan, state_to_string(chan->state),
601 sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300602
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300603 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300604 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100605 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300606 break;
607
608 case BT_CONNECTED:
609 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300610 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100611 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300612 __set_chan_timer(chan, sk->sk_sndtimeo);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300613 l2cap_send_disconn_req(conn, chan, reason);
614 } else
615 l2cap_chan_del(chan, reason);
616 break;
617
618 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300619 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100620 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300621 struct l2cap_conn_rsp rsp;
622 __u16 result;
623
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300624 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300625 result = L2CAP_CR_SEC_BLOCK;
626 else
627 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300628 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300629
630 rsp.scid = cpu_to_le16(chan->dcid);
631 rsp.dcid = cpu_to_le16(chan->scid);
632 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300633 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300634 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100635 sizeof(rsp), &rsp);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300636 }
637
638 l2cap_chan_del(chan, reason);
639 break;
640
641 case BT_CONNECT:
642 case BT_DISCONN:
643 l2cap_chan_del(chan, reason);
644 break;
645
646 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100647 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300648 break;
649 }
650}
651
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300652static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530653{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300654 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300655 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530656 case BT_SECURITY_HIGH:
657 return HCI_AT_DEDICATED_BONDING_MITM;
658 case BT_SECURITY_MEDIUM:
659 return HCI_AT_DEDICATED_BONDING;
660 default:
661 return HCI_AT_NO_BONDING;
662 }
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +0300663 } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300664 if (chan->sec_level == BT_SECURITY_LOW)
665 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530666
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300667 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530668 return HCI_AT_NO_BONDING_MITM;
669 else
670 return HCI_AT_NO_BONDING;
671 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300672 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530673 case BT_SECURITY_HIGH:
674 return HCI_AT_GENERAL_BONDING_MITM;
675 case BT_SECURITY_MEDIUM:
676 return HCI_AT_GENERAL_BONDING;
677 default:
678 return HCI_AT_NO_BONDING;
679 }
680 }
681}
682
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200683/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200684int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200685{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300686 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100687 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200688
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300689 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100690
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300691 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200692}
693
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200694static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200695{
696 u8 id;
697
698 /* Get next available identificator.
699 * 1 - 128 are used by kernel.
700 * 129 - 199 are reserved.
701 * 200 - 254 are used by utilities like l2ping, etc.
702 */
703
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200704 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200705
706 if (++conn->tx_ident > 128)
707 conn->tx_ident = 1;
708
709 id = conn->tx_ident;
710
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200711 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200712
713 return id;
714}
715
Gustavo Padovan2d792812012-10-06 10:07:01 +0100716static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
717 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200718{
719 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200720 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200721
722 BT_DBG("code 0x%2.2x", code);
723
724 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300725 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200726
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200727 if (lmp_no_flush_capable(conn->hcon->hdev))
728 flags = ACL_START_NO_FLUSH;
729 else
730 flags = ACL_START;
731
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700732 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200733 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700734
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200735 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200736}
737
Mat Martineau02b0fbb2012-10-23 15:24:10 -0700738static bool __chan_is_moving(struct l2cap_chan *chan)
739{
740 return chan->move_state != L2CAP_MOVE_STABLE &&
741 chan->move_state != L2CAP_MOVE_WAIT_PREPARE;
742}
743
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200744static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
745{
746 struct hci_conn *hcon = chan->conn->hcon;
747 u16 flags;
748
749 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100750 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200751
752 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100753 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200754 flags = ACL_START_NO_FLUSH;
755 else
756 flags = ACL_START;
757
758 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
759 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760}
761
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700762static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
763{
764 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
765 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
766
767 if (enh & L2CAP_CTRL_FRAME_TYPE) {
768 /* S-Frame */
769 control->sframe = 1;
770 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
771 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
772
773 control->sar = 0;
774 control->txseq = 0;
775 } else {
776 /* I-Frame */
777 control->sframe = 0;
778 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
779 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
780
781 control->poll = 0;
782 control->super = 0;
783 }
784}
785
786static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
787{
788 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
789 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
790
791 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
792 /* S-Frame */
793 control->sframe = 1;
794 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
795 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
796
797 control->sar = 0;
798 control->txseq = 0;
799 } else {
800 /* I-Frame */
801 control->sframe = 0;
802 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
803 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
804
805 control->poll = 0;
806 control->super = 0;
807 }
808}
809
810static inline void __unpack_control(struct l2cap_chan *chan,
811 struct sk_buff *skb)
812{
813 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
814 __unpack_extended_control(get_unaligned_le32(skb->data),
815 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700816 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700817 } else {
818 __unpack_enhanced_control(get_unaligned_le16(skb->data),
819 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700820 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700821 }
822}
823
824static u32 __pack_extended_control(struct l2cap_ctrl *control)
825{
826 u32 packed;
827
828 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
829 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
830
831 if (control->sframe) {
832 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
833 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
834 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
835 } else {
836 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
837 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
838 }
839
840 return packed;
841}
842
843static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
844{
845 u16 packed;
846
847 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
848 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
849
850 if (control->sframe) {
851 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
852 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
853 packed |= L2CAP_CTRL_FRAME_TYPE;
854 } else {
855 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
856 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
857 }
858
859 return packed;
860}
861
862static inline void __pack_control(struct l2cap_chan *chan,
863 struct l2cap_ctrl *control,
864 struct sk_buff *skb)
865{
866 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
867 put_unaligned_le32(__pack_extended_control(control),
868 skb->data + L2CAP_HDR_SIZE);
869 } else {
870 put_unaligned_le16(__pack_enhanced_control(control),
871 skb->data + L2CAP_HDR_SIZE);
872 }
873}
874
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300875static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
876{
877 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
878 return L2CAP_EXT_HDR_SIZE;
879 else
880 return L2CAP_ENH_HDR_SIZE;
881}
882
Mat Martineaua67d7f62012-05-17 20:53:35 -0700883static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
884 u32 control)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -0300885{
886 struct sk_buff *skb;
887 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300888 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -0300889
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -0300890 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300891 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -0300892
Mat Martineaua67d7f62012-05-17 20:53:35 -0700893 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -0300894
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -0300895 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700896 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -0300897
898 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300899 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300900 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300901
Mat Martineaua67d7f62012-05-17 20:53:35 -0700902 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
903 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
904 else
905 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -0300906
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300907 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700908 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300909 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300910 }
911
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200912 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700913 return skb;
914}
915
916static void l2cap_send_sframe(struct l2cap_chan *chan,
917 struct l2cap_ctrl *control)
918{
919 struct sk_buff *skb;
920 u32 control_field;
921
922 BT_DBG("chan %p, control %p", chan, control);
923
924 if (!control->sframe)
925 return;
926
927 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
928 !control->poll)
929 control->final = 1;
930
931 if (control->super == L2CAP_SUPER_RR)
932 clear_bit(CONN_RNR_SENT, &chan->conn_state);
933 else if (control->super == L2CAP_SUPER_RNR)
934 set_bit(CONN_RNR_SENT, &chan->conn_state);
935
936 if (control->super != L2CAP_SUPER_SREJ) {
937 chan->last_acked_seq = control->reqseq;
938 __clear_ack_timer(chan);
939 }
940
941 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
942 control->final, control->poll, control->super);
943
944 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
945 control_field = __pack_extended_control(control);
946 else
947 control_field = __pack_enhanced_control(control);
948
949 skb = l2cap_create_sframe_pdu(chan, control_field);
950 if (!IS_ERR(skb))
951 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -0300952}
953
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700954static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300955{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700956 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300957
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700958 BT_DBG("chan %p, poll %d", chan, poll);
959
960 memset(&control, 0, sizeof(control));
961 control.sframe = 1;
962 control.poll = poll;
963
964 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
965 control.super = L2CAP_SUPER_RNR;
966 else
967 control.super = L2CAP_SUPER_RR;
968
969 control.reqseq = chan->buffer_seq;
970 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300971}
972
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300973static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300974{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -0300975 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300976}
977
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300978static bool __amp_capable(struct l2cap_chan *chan)
979{
980 struct l2cap_conn *conn = chan->conn;
981
982 if (enable_hs &&
983 chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED &&
984 conn->fixed_chan_mask & L2CAP_FC_A2MP)
985 return true;
986 else
987 return false;
988}
989
Andrei Emeltchenko2766be42012-09-27 17:26:21 +0300990void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +0200991{
992 struct l2cap_conn *conn = chan->conn;
993 struct l2cap_conn_req req;
994
995 req.scid = cpu_to_le16(chan->scid);
996 req.psm = chan->psm;
997
998 chan->ident = l2cap_get_ident(conn);
999
1000 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
1001
1002 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
1003}
1004
Mat Martineau02b0fbb2012-10-23 15:24:10 -07001005static void l2cap_move_setup(struct l2cap_chan *chan)
1006{
1007 struct sk_buff *skb;
1008
1009 BT_DBG("chan %p", chan);
1010
1011 if (chan->mode != L2CAP_MODE_ERTM)
1012 return;
1013
1014 __clear_retrans_timer(chan);
1015 __clear_monitor_timer(chan);
1016 __clear_ack_timer(chan);
1017
1018 chan->retry_count = 0;
1019 skb_queue_walk(&chan->tx_q, skb) {
1020 if (bt_cb(skb)->control.retries)
1021 bt_cb(skb)->control.retries = 1;
1022 else
1023 break;
1024 }
1025
1026 chan->expected_tx_seq = chan->buffer_seq;
1027
1028 clear_bit(CONN_REJ_ACT, &chan->conn_state);
1029 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
1030 l2cap_seq_list_clear(&chan->retrans_list);
1031 l2cap_seq_list_clear(&chan->srej_list);
1032 skb_queue_purge(&chan->srej_q);
1033
1034 chan->tx_state = L2CAP_TX_STATE_XMIT;
1035 chan->rx_state = L2CAP_RX_STATE_MOVE;
1036
1037 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
1038}
1039
Mat Martineau5f3847a2012-10-23 15:24:12 -07001040static void l2cap_move_done(struct l2cap_chan *chan)
1041{
1042 u8 move_role = chan->move_role;
1043 BT_DBG("chan %p", chan);
1044
1045 chan->move_state = L2CAP_MOVE_STABLE;
1046 chan->move_role = L2CAP_MOVE_ROLE_NONE;
1047
1048 if (chan->mode != L2CAP_MODE_ERTM)
1049 return;
1050
1051 switch (move_role) {
1052 case L2CAP_MOVE_ROLE_INITIATOR:
1053 l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL);
1054 chan->rx_state = L2CAP_RX_STATE_WAIT_F;
1055 break;
1056 case L2CAP_MOVE_ROLE_RESPONDER:
1057 chan->rx_state = L2CAP_RX_STATE_WAIT_P;
1058 break;
1059 }
1060}
1061
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001062static void l2cap_chan_ready(struct l2cap_chan *chan)
1063{
Mat Martineau28270112012-05-17 21:14:09 -07001064 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001065 chan->conf_state = 0;
1066 __clear_chan_timer(chan);
1067
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -03001068 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001069
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +03001070 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001071}
1072
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001073static void l2cap_start_connection(struct l2cap_chan *chan)
1074{
1075 if (__amp_capable(chan)) {
1076 BT_DBG("chan %p AMP capable: discover AMPs", chan);
1077 a2mp_discover_amp(chan);
1078 } else {
1079 l2cap_send_conn_req(chan);
1080 }
1081}
1082
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001083static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001084{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001085 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001086
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001087 if (conn->hcon->type == LE_LINK) {
1088 l2cap_chan_ready(chan);
1089 return;
1090 }
1091
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001092 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001093 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1094 return;
1095
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001096 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001097 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001098 l2cap_start_connection(chan);
1099 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001100 } else {
1101 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001102 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001103
1104 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1105 conn->info_ident = l2cap_get_ident(conn);
1106
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001107 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001108
Gustavo Padovan2d792812012-10-06 10:07:01 +01001109 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1110 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001111 }
1112}
1113
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001114static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1115{
1116 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001117 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001118 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1119
1120 switch (mode) {
1121 case L2CAP_MODE_ERTM:
1122 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1123 case L2CAP_MODE_STREAMING:
1124 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1125 default:
1126 return 0x00;
1127 }
1128}
1129
Gustavo Padovan2d792812012-10-06 10:07:01 +01001130static void l2cap_send_disconn_req(struct l2cap_conn *conn,
1131 struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001132{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001133 struct sock *sk = chan->sk;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001134 struct l2cap_disconn_req req;
1135
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001136 if (!conn)
1137 return;
1138
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001139 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001140 __clear_retrans_timer(chan);
1141 __clear_monitor_timer(chan);
1142 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001143 }
1144
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001145 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001146 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001147 return;
1148 }
1149
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001150 req.dcid = cpu_to_le16(chan->dcid);
1151 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001152 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1153 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001154
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001155 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001156 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001157 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001158 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001159}
1160
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001162static void l2cap_conn_start(struct l2cap_conn *conn)
1163{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001164 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001165
1166 BT_DBG("conn %p", conn);
1167
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001168 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001169
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001170 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001171 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001172
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001173 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001174
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001175 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001176 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001177 continue;
1178 }
1179
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001180 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001181 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001182 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001183 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de72010-07-09 16:38:35 -03001184 continue;
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02001185 }
Gustavo F. Padovan47731de72010-07-09 16:38:35 -03001186
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001187 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001188 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001189 &chan->conf_state)) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001190 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001191 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de72010-07-09 16:38:35 -03001192 continue;
1193 }
1194
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001195 l2cap_start_connection(chan);
Gustavo F. Padovan47731de72010-07-09 16:38:35 -03001196
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001197 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001198 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001199 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001200 rsp.scid = cpu_to_le16(chan->dcid);
1201 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001202
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001203 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001204 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001205 if (test_bit(BT_SK_DEFER_SETUP,
1206 &bt_sk(sk)->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001207 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1208 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001209 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001210
1211 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001212 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001213 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1214 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001215 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001216 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001217 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001218 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1219 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001220 }
1221
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001222 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001223 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001224
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001225 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001226 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001227 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001228 continue;
1229 }
1230
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001231 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001232 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001233 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001234 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001235 }
1236
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001237 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001238 }
1239
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001240 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001241}
1242
Ido Yarivc2287682012-04-20 15:46:07 -03001243/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001244 * Returns closest match, locked.
1245 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001246static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001247 bdaddr_t *src,
1248 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001249{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001250 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001251
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001252 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001253
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001254 list_for_each_entry(c, &chan_list, global_l) {
1255 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001256
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001257 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001258 continue;
1259
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001260 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001261 int src_match, dst_match;
1262 int src_any, dst_any;
1263
Ville Tervob62f3282011-02-10 22:38:50 -03001264 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001265 src_match = !bacmp(&bt_sk(sk)->src, src);
1266 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1267 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001268 read_unlock(&chan_list_lock);
1269 return c;
1270 }
Ville Tervob62f3282011-02-10 22:38:50 -03001271
1272 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001273 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1274 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1275 if ((src_match && dst_any) || (src_any && dst_match) ||
1276 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001277 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001278 }
1279 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001280
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001281 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001282
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001283 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001284}
1285
1286static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1287{
Gustavo F. Padovanc916fbe2011-04-04 16:00:55 -03001288 struct sock *parent, *sk;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001289 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001290
1291 BT_DBG("");
1292
1293 /* Check if we have socket listening on cid */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001294 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
Ido Yarivc2287682012-04-20 15:46:07 -03001295 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001296 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001297 return;
1298
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001299 parent = pchan->sk;
1300
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001301 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001302
Gustavo Padovan80b98022012-05-27 22:27:51 -03001303 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001304 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001305 goto clean;
1306
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001307 sk = chan->sk;
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001308
Ville Tervob62f3282011-02-10 22:38:50 -03001309 hci_conn_hold(conn->hcon);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001310 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
Ville Tervob62f3282011-02-10 22:38:50 -03001311
Ville Tervob62f3282011-02-10 22:38:50 -03001312 bacpy(&bt_sk(sk)->src, conn->src);
1313 bacpy(&bt_sk(sk)->dst, conn->dst);
1314
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001315 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001316
Gustavo Padovan6754e0d2012-05-25 09:30:56 -03001317 l2cap_chan_ready(chan);
Ville Tervob62f3282011-02-10 22:38:50 -03001318
Ville Tervob62f3282011-02-10 22:38:50 -03001319clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001320 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001321}
1322
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001323static void l2cap_conn_ready(struct l2cap_conn *conn)
1324{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001325 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001326 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001327
1328 BT_DBG("conn %p", conn);
1329
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001330 if (!hcon->out && hcon->type == LE_LINK)
Ville Tervob62f3282011-02-10 22:38:50 -03001331 l2cap_le_conn_ready(conn);
1332
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001333 if (hcon->out && hcon->type == LE_LINK)
1334 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001335
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001336 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001337
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001338 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001339
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001340 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001341
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001342 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1343 l2cap_chan_unlock(chan);
1344 continue;
1345 }
1346
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001347 if (hcon->type == LE_LINK) {
1348 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001349 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001350
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001351 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001352 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001353 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001354 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001355 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001356 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001357 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001358
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001359 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001360 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001361
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001362 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001363 }
1364
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001365 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001366}
1367
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001368/* Notify sockets that we cannot guaranty reliability anymore */
1369static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1370{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001371 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001372
1373 BT_DBG("conn %p", conn);
1374
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001375 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001376
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001377 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001378 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001379 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001380 }
1381
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001382 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001383}
1384
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001385static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001386{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001387 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001388 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001389
Marcel Holtmann984947d2009-02-06 23:35:19 +01001390 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001391 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001392
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001393 l2cap_conn_start(conn);
1394}
1395
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001396static void l2cap_conn_del(struct hci_conn *hcon, int err)
1397{
1398 struct l2cap_conn *conn = hcon->l2cap_data;
1399 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001400
1401 if (!conn)
1402 return;
1403
1404 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1405
1406 kfree_skb(conn->rx_skb);
1407
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001408 mutex_lock(&conn->chan_lock);
1409
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001410 /* Kill channels */
1411 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001412 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001413 l2cap_chan_lock(chan);
1414
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001415 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001416
1417 l2cap_chan_unlock(chan);
1418
Gustavo Padovan80b98022012-05-27 22:27:51 -03001419 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001420 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001421 }
1422
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001423 mutex_unlock(&conn->chan_lock);
1424
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001425 hci_chan_del(conn->hchan);
1426
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001427 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001428 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001429
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001430 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001431 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001432 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001433 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001434
1435 hcon->l2cap_data = NULL;
1436 kfree(conn);
1437}
1438
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001439static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001440{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001441 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001442 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001443
Johan Hedbergd06cc412012-06-06 18:44:11 +08001444 BT_DBG("conn %p", conn);
1445
1446 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1447 smp_chan_destroy(conn);
1448 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1449 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001450}
1451
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
1453{
Marcel Holtmann01394182006-07-03 10:02:46 +02001454 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001455 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456
Marcel Holtmann01394182006-07-03 10:02:46 +02001457 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001458 return conn;
1459
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001460 hchan = hci_chan_create(hcon);
1461 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001464 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001465 if (!conn) {
1466 hci_chan_del(hchan);
1467 return NULL;
1468 }
1469
Linus Torvalds1da177e2005-04-16 15:20:36 -07001470 hcon->l2cap_data = conn;
1471 conn->hcon = hcon;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001472 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001474 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001475
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001476 switch (hcon->type) {
1477 case AMP_LINK:
1478 conn->mtu = hcon->hdev->block_mtu;
1479 break;
1480
1481 case LE_LINK:
1482 if (hcon->hdev->le_mtu) {
1483 conn->mtu = hcon->hdev->le_mtu;
1484 break;
1485 }
1486 /* fall through */
1487
1488 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001489 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001490 break;
1491 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001492
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493 conn->src = &hcon->hdev->bdaddr;
1494 conn->dst = &hcon->dst;
1495
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001496 conn->feat_mask = 0;
1497
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001499 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001500
1501 INIT_LIST_HEAD(&conn->chan_l);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001503 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001504 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001505 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001506 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001507
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001508 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001509
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510 return conn;
1511}
1512
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001514
Ido Yarivc2287682012-04-20 15:46:07 -03001515/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516 * Returns closest match.
1517 */
Ido Yarivc2287682012-04-20 15:46:07 -03001518static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1519 bdaddr_t *src,
1520 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001522 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001524 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001525
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001526 list_for_each_entry(c, &chan_list, global_l) {
1527 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001528
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001529 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530 continue;
1531
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001532 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001533 int src_match, dst_match;
1534 int src_any, dst_any;
1535
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001537 src_match = !bacmp(&bt_sk(sk)->src, src);
1538 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1539 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001540 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001541 return c;
1542 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543
1544 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001545 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1546 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1547 if ((src_match && dst_any) || (src_any && dst_match) ||
1548 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001549 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550 }
1551 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001553 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001554
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001555 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556}
1557
Andre Guedes8e9f9892012-04-24 21:02:55 -03001558int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1559 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001561 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563 struct l2cap_conn *conn;
1564 struct hci_conn *hcon;
1565 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001566 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001567 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001569 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301570 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001572 hdev = hci_get_route(dst, src);
1573 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 return -EHOSTUNREACH;
1575
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001576 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001578 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001579
1580 /* PSM must be odd and lsb of upper byte must be 0 */
1581 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001582 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001583 err = -EINVAL;
1584 goto done;
1585 }
1586
1587 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1588 err = -EINVAL;
1589 goto done;
1590 }
1591
1592 switch (chan->mode) {
1593 case L2CAP_MODE_BASIC:
1594 break;
1595 case L2CAP_MODE_ERTM:
1596 case L2CAP_MODE_STREAMING:
1597 if (!disable_ertm)
1598 break;
1599 /* fall through */
1600 default:
1601 err = -ENOTSUPP;
1602 goto done;
1603 }
1604
Gustavo Padovan0797e012012-05-27 22:27:54 -03001605 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001606 case BT_CONNECT:
1607 case BT_CONNECT2:
1608 case BT_CONFIG:
1609 /* Already connecting */
1610 err = 0;
1611 goto done;
1612
1613 case BT_CONNECTED:
1614 /* Already connected */
1615 err = -EISCONN;
1616 goto done;
1617
1618 case BT_OPEN:
1619 case BT_BOUND:
1620 /* Can connect */
1621 break;
1622
1623 default:
1624 err = -EBADFD;
1625 goto done;
1626 }
1627
1628 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001629 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001630 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001631 release_sock(sk);
1632
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001633 chan->psm = psm;
1634 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001635
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001636 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001637
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001638 if (chan->dcid == L2CAP_CID_LE_DATA)
Andre Guedes8e9f9892012-04-24 21:02:55 -03001639 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001640 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001641 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001642 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001643 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001644
Ville Tervo30e76272011-02-22 16:10:53 -03001645 if (IS_ERR(hcon)) {
1646 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001647 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001648 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001649
1650 conn = l2cap_conn_add(hcon, 0);
1651 if (!conn) {
1652 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001653 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654 goto done;
1655 }
1656
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001657 if (hcon->type == LE_LINK) {
1658 err = 0;
1659
1660 if (!list_empty(&conn->chan_l)) {
1661 err = -EBUSY;
1662 hci_conn_put(hcon);
1663 }
1664
1665 if (err)
1666 goto done;
1667 }
1668
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669 /* Update source addr of the socket */
1670 bacpy(src, conn->src);
1671
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001672 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001673 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001674 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001675
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001676 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001677 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678
1679 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001680 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001681 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001682 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001683 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001684 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001685 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686 }
1687
Ville Tervo30e76272011-02-22 16:10:53 -03001688 err = 0;
1689
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001691 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001692 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693 hci_dev_put(hdev);
1694 return err;
1695}
1696
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001697int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001698{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001699 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001700 DECLARE_WAITQUEUE(wait, current);
1701 int err = 0;
1702 int timeo = HZ/5;
1703
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001704 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001705 set_current_state(TASK_INTERRUPTIBLE);
1706 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001707 if (!timeo)
1708 timeo = HZ/5;
1709
1710 if (signal_pending(current)) {
1711 err = sock_intr_errno(timeo);
1712 break;
1713 }
1714
1715 release_sock(sk);
1716 timeo = schedule_timeout(timeo);
1717 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001718 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001719
1720 err = sock_error(sk);
1721 if (err)
1722 break;
1723 }
1724 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001725 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001726 return err;
1727}
1728
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001729static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001730{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001731 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001732 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001733
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001734 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001735
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001736 l2cap_chan_lock(chan);
1737
Mat Martineau80909e02012-05-17 20:53:50 -07001738 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001739 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001740 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001741 return;
1742 }
1743
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001744 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001745
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001746 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001747 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001748}
1749
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001750static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001751{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001752 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001753 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001754
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001755 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001756
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001757 l2cap_chan_lock(chan);
1758
Mat Martineau80909e02012-05-17 20:53:50 -07001759 if (!chan->conn) {
1760 l2cap_chan_unlock(chan);
1761 l2cap_chan_put(chan);
1762 return;
1763 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001764
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001765 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001766 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001767 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001768}
1769
Gustavo Padovand6603662012-05-21 13:58:22 -03001770static void l2cap_streaming_send(struct l2cap_chan *chan,
1771 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001772{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001773 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001774 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001775
Mat Martineau37339372012-05-17 20:53:33 -07001776 BT_DBG("chan %p, skbs %p", chan, skbs);
1777
Mat Martineau37339372012-05-17 20:53:33 -07001778 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1779
1780 while (!skb_queue_empty(&chan->tx_q)) {
1781
1782 skb = skb_dequeue(&chan->tx_q);
1783
1784 bt_cb(skb)->control.retries = 1;
1785 control = &bt_cb(skb)->control;
1786
1787 control->reqseq = 0;
1788 control->txseq = chan->next_tx_seq;
1789
1790 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001791
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001792 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001793 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1794 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001795 }
1796
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001797 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001798
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001799 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001800
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001801 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001802 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001803 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001804}
1805
Szymon Janc67c9e842011-07-28 16:24:33 +02001806static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001807{
1808 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001809 struct l2cap_ctrl *control;
1810 int sent = 0;
1811
1812 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001813
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001814 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001815 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001816
Mat Martineau94122bb2012-05-02 09:42:02 -07001817 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1818 return 0;
1819
Mat Martineau18a48e72012-05-17 20:53:34 -07001820 while (chan->tx_send_head &&
1821 chan->unacked_frames < chan->remote_tx_win &&
1822 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001823
Mat Martineau18a48e72012-05-17 20:53:34 -07001824 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001825
Mat Martineau18a48e72012-05-17 20:53:34 -07001826 bt_cb(skb)->control.retries = 1;
1827 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001828
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001829 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001830 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001831
Mat Martineau18a48e72012-05-17 20:53:34 -07001832 control->reqseq = chan->buffer_seq;
1833 chan->last_acked_seq = chan->buffer_seq;
1834 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001835
Mat Martineau18a48e72012-05-17 20:53:34 -07001836 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001837
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001838 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001839 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1840 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001841 }
1842
Mat Martineau18a48e72012-05-17 20:53:34 -07001843 /* Clone after data has been modified. Data is assumed to be
1844 read-only (for locking purposes) on cloned sk_buffs.
1845 */
1846 tx_skb = skb_clone(skb, GFP_KERNEL);
1847
1848 if (!tx_skb)
1849 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001850
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001851 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001852
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001853 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07001854 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03001855 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07001856 sent++;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001857
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001858 if (skb_queue_is_last(&chan->tx_q, skb))
1859 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001860 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001861 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07001862
1863 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001864 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03001865 }
1866
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001867 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
1868 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07001869
1870 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001871}
1872
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001873static void l2cap_ertm_resend(struct l2cap_chan *chan)
1874{
1875 struct l2cap_ctrl control;
1876 struct sk_buff *skb;
1877 struct sk_buff *tx_skb;
1878 u16 seq;
1879
1880 BT_DBG("chan %p", chan);
1881
1882 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1883 return;
1884
1885 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
1886 seq = l2cap_seq_list_pop(&chan->retrans_list);
1887
1888 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
1889 if (!skb) {
1890 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01001891 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001892 continue;
1893 }
1894
1895 bt_cb(skb)->control.retries++;
1896 control = bt_cb(skb)->control;
1897
1898 if (chan->max_tx != 0 &&
1899 bt_cb(skb)->control.retries > chan->max_tx) {
1900 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
1901 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
1902 l2cap_seq_list_clear(&chan->retrans_list);
1903 break;
1904 }
1905
1906 control.reqseq = chan->buffer_seq;
1907 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
1908 control.final = 1;
1909 else
1910 control.final = 0;
1911
1912 if (skb_cloned(skb)) {
1913 /* Cloned sk_buffs are read-only, so we need a
1914 * writeable copy
1915 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001916 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001917 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001918 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001919 }
1920
1921 if (!tx_skb) {
1922 l2cap_seq_list_clear(&chan->retrans_list);
1923 break;
1924 }
1925
1926 /* Update skb contents */
1927 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
1928 put_unaligned_le32(__pack_extended_control(&control),
1929 tx_skb->data + L2CAP_HDR_SIZE);
1930 } else {
1931 put_unaligned_le16(__pack_enhanced_control(&control),
1932 tx_skb->data + L2CAP_HDR_SIZE);
1933 }
1934
1935 if (chan->fcs == L2CAP_FCS_CRC16) {
1936 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
1937 put_unaligned_le16(fcs, skb_put(tx_skb,
1938 L2CAP_FCS_SIZE));
1939 }
1940
1941 l2cap_do_send(chan, tx_skb);
1942
1943 BT_DBG("Resent txseq %d", control.txseq);
1944
1945 chan->last_acked_seq = chan->buffer_seq;
1946 }
1947}
1948
Mat Martineauf80842a2012-05-17 20:53:46 -07001949static void l2cap_retransmit(struct l2cap_chan *chan,
1950 struct l2cap_ctrl *control)
1951{
1952 BT_DBG("chan %p, control %p", chan, control);
1953
1954 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
1955 l2cap_ertm_resend(chan);
1956}
1957
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001958static void l2cap_retransmit_all(struct l2cap_chan *chan,
1959 struct l2cap_ctrl *control)
1960{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001961 struct sk_buff *skb;
1962
1963 BT_DBG("chan %p, control %p", chan, control);
1964
1965 if (control->poll)
1966 set_bit(CONN_SEND_FBIT, &chan->conn_state);
1967
1968 l2cap_seq_list_clear(&chan->retrans_list);
1969
1970 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1971 return;
1972
1973 if (chan->unacked_frames) {
1974 skb_queue_walk(&chan->tx_q, skb) {
1975 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001976 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001977 break;
1978 }
1979
1980 skb_queue_walk_from(&chan->tx_q, skb) {
1981 if (skb == chan->tx_send_head)
1982 break;
1983
1984 l2cap_seq_list_append(&chan->retrans_list,
1985 bt_cb(skb)->control.txseq);
1986 }
1987
1988 l2cap_ertm_resend(chan);
1989 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001990}
1991
Szymon Jancb17e73b2012-01-11 10:59:47 +01001992static void l2cap_send_ack(struct l2cap_chan *chan)
1993{
Mat Martineau0a0aba42012-05-17 20:53:39 -07001994 struct l2cap_ctrl control;
1995 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
1996 chan->last_acked_seq);
1997 int threshold;
1998
1999 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
2000 chan, chan->last_acked_seq, chan->buffer_seq);
2001
2002 memset(&control, 0, sizeof(control));
2003 control.sframe = 1;
2004
2005 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
2006 chan->rx_state == L2CAP_RX_STATE_RECV) {
2007 __clear_ack_timer(chan);
2008 control.super = L2CAP_SUPER_RNR;
2009 control.reqseq = chan->buffer_seq;
2010 l2cap_send_sframe(chan, &control);
2011 } else {
2012 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
2013 l2cap_ertm_send(chan);
2014 /* If any i-frames were sent, they included an ack */
2015 if (chan->buffer_seq == chan->last_acked_seq)
2016 frames_to_ack = 0;
2017 }
2018
Mat Martineauc20f8e32012-07-10 05:47:07 -07002019 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07002020 * Calculate without mul or div
2021 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07002022 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07002023 threshold += threshold << 1;
2024 threshold >>= 2;
2025
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002026 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07002027 threshold);
2028
2029 if (frames_to_ack >= threshold) {
2030 __clear_ack_timer(chan);
2031 control.super = L2CAP_SUPER_RR;
2032 control.reqseq = chan->buffer_seq;
2033 l2cap_send_sframe(chan, &control);
2034 frames_to_ack = 0;
2035 }
2036
2037 if (frames_to_ack)
2038 __set_ack_timer(chan);
2039 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01002040}
2041
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002042static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
2043 struct msghdr *msg, int len,
2044 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002045{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002046 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002047 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03002048 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002049
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03002050 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002051 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002052
2053 sent += count;
2054 len -= count;
2055
2056 /* Continuation fragments (no L2CAP header) */
2057 frag = &skb_shinfo(skb)->frag_list;
2058 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002059 struct sk_buff *tmp;
2060
Linus Torvalds1da177e2005-04-16 15:20:36 -07002061 count = min_t(unsigned int, conn->mtu, len);
2062
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002063 tmp = chan->ops->alloc_skb(chan, count,
2064 msg->msg_flags & MSG_DONTWAIT);
2065 if (IS_ERR(tmp))
2066 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002067
Gustavo Padovanfbe00702012-05-15 13:22:55 -03002068 *frag = tmp;
2069
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002070 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
2071 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002072
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002073 (*frag)->priority = skb->priority;
2074
Linus Torvalds1da177e2005-04-16 15:20:36 -07002075 sent += count;
2076 len -= count;
2077
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03002078 skb->len += (*frag)->len;
2079 skb->data_len += (*frag)->len;
2080
Linus Torvalds1da177e2005-04-16 15:20:36 -07002081 frag = &(*frag)->next;
2082 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002083
2084 return sent;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002085}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002087static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002088 struct msghdr *msg, size_t len,
2089 u32 priority)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002090{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002091 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002092 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002093 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002094 struct l2cap_hdr *lh;
2095
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002096 BT_DBG("chan %p len %zu priority %u", chan, len, priority);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002097
2098 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002099
2100 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002101 msg->msg_flags & MSG_DONTWAIT);
2102 if (IS_ERR(skb))
2103 return skb;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002104
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002105 skb->priority = priority;
2106
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002107 /* Create L2CAP header */
2108 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002109 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002110 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
2111 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002112
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002113 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002114 if (unlikely(err < 0)) {
2115 kfree_skb(skb);
2116 return ERR_PTR(err);
2117 }
2118 return skb;
2119}
2120
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002121static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002122 struct msghdr *msg, size_t len,
2123 u32 priority)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002124{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002125 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002126 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002127 int err, count;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002128 struct l2cap_hdr *lh;
2129
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002130 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002131
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002132 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002133
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002134 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002135 msg->msg_flags & MSG_DONTWAIT);
2136 if (IS_ERR(skb))
2137 return skb;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002138
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002139 skb->priority = priority;
2140
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002141 /* Create L2CAP header */
2142 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002143 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002144 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002145
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002146 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002147 if (unlikely(err < 0)) {
2148 kfree_skb(skb);
2149 return ERR_PTR(err);
2150 }
2151 return skb;
2152}
2153
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002154static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002155 struct msghdr *msg, size_t len,
2156 u16 sdulen)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002157{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002158 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002159 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002160 int err, count, hlen;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002161 struct l2cap_hdr *lh;
2162
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002163 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002164
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002165 if (!conn)
2166 return ERR_PTR(-ENOTCONN);
2167
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002168 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002169
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002170 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002171 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002172
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002173 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002174 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002175
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002176 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002177
2178 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002179 msg->msg_flags & MSG_DONTWAIT);
2180 if (IS_ERR(skb))
2181 return skb;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002182
2183 /* Create L2CAP header */
2184 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002185 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002186 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002187
Mat Martineau18a48e72012-05-17 20:53:34 -07002188 /* Control header is populated later */
2189 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2190 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2191 else
2192 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002193
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002194 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002195 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002196
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002197 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002198 if (unlikely(err < 0)) {
2199 kfree_skb(skb);
2200 return ERR_PTR(err);
2201 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002202
Mat Martineau18a48e72012-05-17 20:53:34 -07002203 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002204 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03002205 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002206}
2207
Mat Martineau94122bb2012-05-02 09:42:02 -07002208static int l2cap_segment_sdu(struct l2cap_chan *chan,
2209 struct sk_buff_head *seg_queue,
2210 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002211{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002212 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002213 u16 sdu_len;
2214 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002215 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002216
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002217 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002218
Mat Martineau94122bb2012-05-02 09:42:02 -07002219 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2220 * so fragmented skbs are not used. The HCI layer's handling
2221 * of fragmented skbs is not compatible with ERTM's queueing.
2222 */
2223
2224 /* PDU size is derived from the HCI MTU */
2225 pdu_len = chan->conn->mtu;
2226
2227 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
2228
2229 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002230 if (chan->fcs)
2231 pdu_len -= L2CAP_FCS_SIZE;
2232
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002233 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002234
2235 /* Remote device may have requested smaller PDUs */
2236 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2237
2238 if (len <= pdu_len) {
2239 sar = L2CAP_SAR_UNSEGMENTED;
2240 sdu_len = 0;
2241 pdu_len = len;
2242 } else {
2243 sar = L2CAP_SAR_START;
2244 sdu_len = len;
2245 pdu_len -= L2CAP_SDULEN_SIZE;
2246 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002247
2248 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002249 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002250
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002251 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002252 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002253 return PTR_ERR(skb);
2254 }
2255
Mat Martineau94122bb2012-05-02 09:42:02 -07002256 bt_cb(skb)->control.sar = sar;
2257 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002258
Mat Martineau94122bb2012-05-02 09:42:02 -07002259 len -= pdu_len;
2260 if (sdu_len) {
2261 sdu_len = 0;
2262 pdu_len += L2CAP_SDULEN_SIZE;
2263 }
2264
2265 if (len <= pdu_len) {
2266 sar = L2CAP_SAR_END;
2267 pdu_len = len;
2268 } else {
2269 sar = L2CAP_SAR_CONTINUE;
2270 }
2271 }
2272
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002273 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002274}
2275
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002276int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002277 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002278{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002279 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002280 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002281 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002282
2283 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002284 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002285 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002286 if (IS_ERR(skb))
2287 return PTR_ERR(skb);
2288
2289 l2cap_do_send(chan, skb);
2290 return len;
2291 }
2292
2293 switch (chan->mode) {
2294 case L2CAP_MODE_BASIC:
2295 /* Check outgoing MTU */
2296 if (len > chan->omtu)
2297 return -EMSGSIZE;
2298
2299 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002300 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002301 if (IS_ERR(skb))
2302 return PTR_ERR(skb);
2303
2304 l2cap_do_send(chan, skb);
2305 err = len;
2306 break;
2307
2308 case L2CAP_MODE_ERTM:
2309 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002310 /* Check outgoing MTU */
2311 if (len > chan->omtu) {
2312 err = -EMSGSIZE;
2313 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002314 }
2315
Mat Martineau94122bb2012-05-02 09:42:02 -07002316 __skb_queue_head_init(&seg_queue);
2317
2318 /* Do segmentation before calling in to the state machine,
2319 * since it's possible to block while waiting for memory
2320 * allocation.
2321 */
2322 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2323
2324 /* The channel could have been closed while segmenting,
2325 * check that it is still connected.
2326 */
2327 if (chan->state != BT_CONNECTED) {
2328 __skb_queue_purge(&seg_queue);
2329 err = -ENOTCONN;
2330 }
2331
2332 if (err)
2333 break;
2334
Mat Martineau37339372012-05-17 20:53:33 -07002335 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002336 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002337 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002338 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002339
Gustavo Padovand6603662012-05-21 13:58:22 -03002340 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002341
Mat Martineau94122bb2012-05-02 09:42:02 -07002342 /* If the skbs were not queued for sending, they'll still be in
2343 * seg_queue and need to be purged.
2344 */
2345 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002346 break;
2347
2348 default:
2349 BT_DBG("bad state %1.1x", chan->mode);
2350 err = -EBADFD;
2351 }
2352
2353 return err;
2354}
2355
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002356static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2357{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002358 struct l2cap_ctrl control;
2359 u16 seq;
2360
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002361 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002362
2363 memset(&control, 0, sizeof(control));
2364 control.sframe = 1;
2365 control.super = L2CAP_SUPER_SREJ;
2366
2367 for (seq = chan->expected_tx_seq; seq != txseq;
2368 seq = __next_seq(chan, seq)) {
2369 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2370 control.reqseq = seq;
2371 l2cap_send_sframe(chan, &control);
2372 l2cap_seq_list_append(&chan->srej_list, seq);
2373 }
2374 }
2375
2376 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002377}
2378
2379static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2380{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002381 struct l2cap_ctrl control;
2382
2383 BT_DBG("chan %p", chan);
2384
2385 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2386 return;
2387
2388 memset(&control, 0, sizeof(control));
2389 control.sframe = 1;
2390 control.super = L2CAP_SUPER_SREJ;
2391 control.reqseq = chan->srej_list.tail;
2392 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002393}
2394
2395static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2396{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002397 struct l2cap_ctrl control;
2398 u16 initial_head;
2399 u16 seq;
2400
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002401 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002402
2403 memset(&control, 0, sizeof(control));
2404 control.sframe = 1;
2405 control.super = L2CAP_SUPER_SREJ;
2406
2407 /* Capture initial list head to allow only one pass through the list. */
2408 initial_head = chan->srej_list.head;
2409
2410 do {
2411 seq = l2cap_seq_list_pop(&chan->srej_list);
2412 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2413 break;
2414
2415 control.reqseq = seq;
2416 l2cap_send_sframe(chan, &control);
2417 l2cap_seq_list_append(&chan->srej_list, seq);
2418 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002419}
2420
Mat Martineau608bcc62012-05-17 20:53:32 -07002421static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2422{
2423 struct sk_buff *acked_skb;
2424 u16 ackseq;
2425
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002426 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002427
2428 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2429 return;
2430
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002431 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002432 chan->expected_ack_seq, chan->unacked_frames);
2433
2434 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2435 ackseq = __next_seq(chan, ackseq)) {
2436
2437 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2438 if (acked_skb) {
2439 skb_unlink(acked_skb, &chan->tx_q);
2440 kfree_skb(acked_skb);
2441 chan->unacked_frames--;
2442 }
2443 }
2444
2445 chan->expected_ack_seq = reqseq;
2446
2447 if (chan->unacked_frames == 0)
2448 __clear_retrans_timer(chan);
2449
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002450 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002451}
2452
2453static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2454{
2455 BT_DBG("chan %p", chan);
2456
2457 chan->expected_tx_seq = chan->buffer_seq;
2458 l2cap_seq_list_clear(&chan->srej_list);
2459 skb_queue_purge(&chan->srej_q);
2460 chan->rx_state = L2CAP_RX_STATE_RECV;
2461}
2462
Gustavo Padovand6603662012-05-21 13:58:22 -03002463static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2464 struct l2cap_ctrl *control,
2465 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002466{
Mat Martineau608bcc62012-05-17 20:53:32 -07002467 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2468 event);
2469
2470 switch (event) {
2471 case L2CAP_EV_DATA_REQUEST:
2472 if (chan->tx_send_head == NULL)
2473 chan->tx_send_head = skb_peek(skbs);
2474
2475 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2476 l2cap_ertm_send(chan);
2477 break;
2478 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2479 BT_DBG("Enter LOCAL_BUSY");
2480 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2481
2482 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2483 /* The SREJ_SENT state must be aborted if we are to
2484 * enter the LOCAL_BUSY state.
2485 */
2486 l2cap_abort_rx_srej_sent(chan);
2487 }
2488
2489 l2cap_send_ack(chan);
2490
2491 break;
2492 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2493 BT_DBG("Exit LOCAL_BUSY");
2494 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2495
2496 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2497 struct l2cap_ctrl local_control;
2498
2499 memset(&local_control, 0, sizeof(local_control));
2500 local_control.sframe = 1;
2501 local_control.super = L2CAP_SUPER_RR;
2502 local_control.poll = 1;
2503 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002504 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002505
2506 chan->retry_count = 1;
2507 __set_monitor_timer(chan);
2508 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2509 }
2510 break;
2511 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2512 l2cap_process_reqseq(chan, control->reqseq);
2513 break;
2514 case L2CAP_EV_EXPLICIT_POLL:
2515 l2cap_send_rr_or_rnr(chan, 1);
2516 chan->retry_count = 1;
2517 __set_monitor_timer(chan);
2518 __clear_ack_timer(chan);
2519 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2520 break;
2521 case L2CAP_EV_RETRANS_TO:
2522 l2cap_send_rr_or_rnr(chan, 1);
2523 chan->retry_count = 1;
2524 __set_monitor_timer(chan);
2525 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2526 break;
2527 case L2CAP_EV_RECV_FBIT:
2528 /* Nothing to process */
2529 break;
2530 default:
2531 break;
2532 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002533}
2534
Gustavo Padovand6603662012-05-21 13:58:22 -03002535static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2536 struct l2cap_ctrl *control,
2537 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002538{
Mat Martineau608bcc62012-05-17 20:53:32 -07002539 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2540 event);
2541
2542 switch (event) {
2543 case L2CAP_EV_DATA_REQUEST:
2544 if (chan->tx_send_head == NULL)
2545 chan->tx_send_head = skb_peek(skbs);
2546 /* Queue data, but don't send. */
2547 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2548 break;
2549 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2550 BT_DBG("Enter LOCAL_BUSY");
2551 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2552
2553 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2554 /* The SREJ_SENT state must be aborted if we are to
2555 * enter the LOCAL_BUSY state.
2556 */
2557 l2cap_abort_rx_srej_sent(chan);
2558 }
2559
2560 l2cap_send_ack(chan);
2561
2562 break;
2563 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2564 BT_DBG("Exit LOCAL_BUSY");
2565 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2566
2567 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2568 struct l2cap_ctrl local_control;
2569 memset(&local_control, 0, sizeof(local_control));
2570 local_control.sframe = 1;
2571 local_control.super = L2CAP_SUPER_RR;
2572 local_control.poll = 1;
2573 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002574 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002575
2576 chan->retry_count = 1;
2577 __set_monitor_timer(chan);
2578 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2579 }
2580 break;
2581 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2582 l2cap_process_reqseq(chan, control->reqseq);
2583
2584 /* Fall through */
2585
2586 case L2CAP_EV_RECV_FBIT:
2587 if (control && control->final) {
2588 __clear_monitor_timer(chan);
2589 if (chan->unacked_frames > 0)
2590 __set_retrans_timer(chan);
2591 chan->retry_count = 0;
2592 chan->tx_state = L2CAP_TX_STATE_XMIT;
2593 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2594 }
2595 break;
2596 case L2CAP_EV_EXPLICIT_POLL:
2597 /* Ignore */
2598 break;
2599 case L2CAP_EV_MONITOR_TO:
2600 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2601 l2cap_send_rr_or_rnr(chan, 1);
2602 __set_monitor_timer(chan);
2603 chan->retry_count++;
2604 } else {
2605 l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
2606 }
2607 break;
2608 default:
2609 break;
2610 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002611}
2612
Gustavo Padovand6603662012-05-21 13:58:22 -03002613static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2614 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002615{
Mat Martineau608bcc62012-05-17 20:53:32 -07002616 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2617 chan, control, skbs, event, chan->tx_state);
2618
2619 switch (chan->tx_state) {
2620 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002621 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002622 break;
2623 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002624 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002625 break;
2626 default:
2627 /* Ignore event */
2628 break;
2629 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002630}
2631
Mat Martineau4b51dae92012-05-17 20:53:37 -07002632static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2633 struct l2cap_ctrl *control)
2634{
2635 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002636 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002637}
2638
Mat Martineauf80842a2012-05-17 20:53:46 -07002639static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2640 struct l2cap_ctrl *control)
2641{
2642 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002643 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002644}
2645
Linus Torvalds1da177e2005-04-16 15:20:36 -07002646/* Copy frame to all raw sockets on that connection */
2647static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2648{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002649 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002650 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002651
2652 BT_DBG("conn %p", conn);
2653
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002654 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002655
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002656 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002657 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002658 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002659 continue;
2660
2661 /* Don't send frame to the socket it came from */
2662 if (skb->sk == sk)
2663 continue;
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002664 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002665 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002666 continue;
2667
Gustavo Padovan80b98022012-05-27 22:27:51 -03002668 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002669 kfree_skb(nskb);
2670 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002671
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002672 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002673}
2674
2675/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002676static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2677 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002678{
2679 struct sk_buff *skb, **frag;
2680 struct l2cap_cmd_hdr *cmd;
2681 struct l2cap_hdr *lh;
2682 int len, count;
2683
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002684 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2685 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002686
2687 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2688 count = min_t(unsigned int, conn->mtu, len);
2689
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002690 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002691 if (!skb)
2692 return NULL;
2693
2694 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002695 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002696
2697 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002698 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002699 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002700 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002701
2702 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2703 cmd->code = code;
2704 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002705 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002706
2707 if (dlen) {
2708 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2709 memcpy(skb_put(skb, count), data, count);
2710 data += count;
2711 }
2712
2713 len -= skb->len;
2714
2715 /* Continuation fragments (no L2CAP header) */
2716 frag = &skb_shinfo(skb)->frag_list;
2717 while (len) {
2718 count = min_t(unsigned int, conn->mtu, len);
2719
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002720 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002721 if (!*frag)
2722 goto fail;
2723
2724 memcpy(skb_put(*frag, count), data, count);
2725
2726 len -= count;
2727 data += count;
2728
2729 frag = &(*frag)->next;
2730 }
2731
2732 return skb;
2733
2734fail:
2735 kfree_skb(skb);
2736 return NULL;
2737}
2738
Gustavo Padovan2d792812012-10-06 10:07:01 +01002739static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2740 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002741{
2742 struct l2cap_conf_opt *opt = *ptr;
2743 int len;
2744
2745 len = L2CAP_CONF_OPT_SIZE + opt->len;
2746 *ptr += len;
2747
2748 *type = opt->type;
2749 *olen = opt->len;
2750
2751 switch (opt->len) {
2752 case 1:
2753 *val = *((u8 *) opt->val);
2754 break;
2755
2756 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002757 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002758 break;
2759
2760 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002761 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002762 break;
2763
2764 default:
2765 *val = (unsigned long) opt->val;
2766 break;
2767 }
2768
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002769 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002770 return len;
2771}
2772
Linus Torvalds1da177e2005-04-16 15:20:36 -07002773static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2774{
2775 struct l2cap_conf_opt *opt = *ptr;
2776
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002777 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002778
2779 opt->type = type;
2780 opt->len = len;
2781
2782 switch (len) {
2783 case 1:
2784 *((u8 *) opt->val) = val;
2785 break;
2786
2787 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002788 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002789 break;
2790
2791 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002792 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002793 break;
2794
2795 default:
2796 memcpy(opt->val, (void *) val, len);
2797 break;
2798 }
2799
2800 *ptr += L2CAP_CONF_OPT_SIZE + len;
2801}
2802
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002803static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2804{
2805 struct l2cap_conf_efs efs;
2806
Szymon Janc1ec918c2011-11-16 09:32:21 +01002807 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002808 case L2CAP_MODE_ERTM:
2809 efs.id = chan->local_id;
2810 efs.stype = chan->local_stype;
2811 efs.msdu = cpu_to_le16(chan->local_msdu);
2812 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002813 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002814 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002815 break;
2816
2817 case L2CAP_MODE_STREAMING:
2818 efs.id = 1;
2819 efs.stype = L2CAP_SERV_BESTEFFORT;
2820 efs.msdu = cpu_to_le16(chan->local_msdu);
2821 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2822 efs.acc_lat = 0;
2823 efs.flush_to = 0;
2824 break;
2825
2826 default:
2827 return;
2828 }
2829
2830 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002831 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002832}
2833
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002834static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002835{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002836 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07002837 ack_timer.work);
2838 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002839
Gustavo F. Padovan2fb9b3d42011-12-22 16:56:05 -02002840 BT_DBG("chan %p", chan);
2841
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002842 l2cap_chan_lock(chan);
2843
Mat Martineau03625202012-05-17 20:53:51 -07002844 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2845 chan->last_acked_seq);
2846
2847 if (frames_to_ack)
2848 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002849
2850 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01002851 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002852}
2853
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03002854int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002855{
Mat Martineau3c588192012-04-11 10:48:42 -07002856 int err;
2857
Mat Martineau105bdf92012-04-27 16:50:48 -07002858 chan->next_tx_seq = 0;
2859 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002860 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002861 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002862 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002863 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07002864 chan->last_acked_seq = 0;
2865 chan->sdu = NULL;
2866 chan->sdu_last_frag = NULL;
2867 chan->sdu_len = 0;
2868
Mat Martineaud34c34f2012-05-14 14:49:27 -07002869 skb_queue_head_init(&chan->tx_q);
2870
Mat Martineau08333282012-10-23 15:24:06 -07002871 chan->local_amp_id = 0;
2872 chan->move_id = 0;
2873 chan->move_state = L2CAP_MOVE_STABLE;
2874 chan->move_role = L2CAP_MOVE_ROLE_NONE;
2875
Mat Martineau105bdf92012-04-27 16:50:48 -07002876 if (chan->mode != L2CAP_MODE_ERTM)
2877 return 0;
2878
2879 chan->rx_state = L2CAP_RX_STATE_RECV;
2880 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002881
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002882 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
2883 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
2884 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002885
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03002886 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002887
Mat Martineau3c588192012-04-11 10:48:42 -07002888 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
2889 if (err < 0)
2890 return err;
2891
Mat Martineau9dc9aff2012-05-17 16:20:14 -07002892 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
2893 if (err < 0)
2894 l2cap_seq_list_free(&chan->srej_list);
2895
2896 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002897}
2898
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002899static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2900{
2901 switch (mode) {
2902 case L2CAP_MODE_STREAMING:
2903 case L2CAP_MODE_ERTM:
2904 if (l2cap_mode_supported(mode, remote_feat_mask))
2905 return mode;
2906 /* fall through */
2907 default:
2908 return L2CAP_MODE_BASIC;
2909 }
2910}
2911
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002912static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
2913{
2914 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
2915}
2916
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002917static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
2918{
2919 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
2920}
2921
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002922static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
2923{
2924 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01002925 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002926 /* use extended control field */
2927 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002928 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
2929 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002930 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002931 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002932 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
2933 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07002934 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002935}
2936
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03002937static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002938{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002939 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002940 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002941 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002942 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002943
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03002944 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002945
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002946 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002947 goto done;
2948
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002949 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002950 case L2CAP_MODE_STREAMING:
2951 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002952 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002953 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002954
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002955 if (__l2cap_efs_supported(chan))
2956 set_bit(FLAG_EFS_ENABLE, &chan->flags);
2957
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002958 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002959 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002960 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002961 break;
2962 }
2963
2964done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002965 if (chan->imtu != L2CAP_DEFAULT_MTU)
2966 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02002967
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002968 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002969 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002970 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01002971 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002972 break;
2973
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002974 rfc.mode = L2CAP_MODE_BASIC;
2975 rfc.txwin_size = 0;
2976 rfc.max_transmit = 0;
2977 rfc.retrans_timeout = 0;
2978 rfc.monitor_timeout = 0;
2979 rfc.max_pdu_size = 0;
2980
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002981 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01002982 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002983 break;
2984
2985 case L2CAP_MODE_ERTM:
2986 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002987 rfc.max_transmit = chan->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002988 rfc.retrans_timeout = 0;
2989 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002990
2991 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01002992 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
2993 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002994 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002995
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002996 l2cap_txwin_setup(chan);
2997
2998 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002999 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003000
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003001 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003002 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003003
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003004 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3005 l2cap_add_opt_efs(&ptr, chan);
3006
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003007 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003008 break;
3009
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003010 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01003011 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003012 chan->fcs = L2CAP_FCS_NONE;
3013 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003014 }
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003015
3016 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3017 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003018 chan->tx_win);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003019 break;
3020
3021 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07003022 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003023 rfc.mode = L2CAP_MODE_STREAMING;
3024 rfc.txwin_size = 0;
3025 rfc.max_transmit = 0;
3026 rfc.retrans_timeout = 0;
3027 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003028
3029 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01003030 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3031 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003032 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003033
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003034 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003035 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03003036
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03003037 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3038 l2cap_add_opt_efs(&ptr, chan);
3039
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003040 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003041 break;
3042
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003043 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01003044 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003045 chan->fcs = L2CAP_FCS_NONE;
3046 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003047 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07003048 break;
3049 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003050
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003051 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003052 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003053
3054 return ptr - data;
3055}
3056
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003057static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003058{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003059 struct l2cap_conf_rsp *rsp = data;
3060 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003061 void *req = chan->conf_req;
3062 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003063 int type, hint, olen;
3064 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003065 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003066 struct l2cap_conf_efs efs;
3067 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02003068 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003069 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003070 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003071
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003072 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01003073
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003074 while (len >= L2CAP_CONF_OPT_SIZE) {
3075 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003076
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03003077 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003078 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003079
3080 switch (type) {
3081 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003082 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003083 break;
3084
3085 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003086 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003087 break;
3088
3089 case L2CAP_CONF_QOS:
3090 break;
3091
Marcel Holtmann6464f352007-10-20 13:39:51 +02003092 case L2CAP_CONF_RFC:
3093 if (olen == sizeof(rfc))
3094 memcpy(&rfc, (void *) val, olen);
3095 break;
3096
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003097 case L2CAP_CONF_FCS:
3098 if (val == L2CAP_FCS_NONE)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003099 set_bit(CONF_NO_FCS_RECV, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003100 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003101
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003102 case L2CAP_CONF_EFS:
3103 remote_efs = 1;
3104 if (olen == sizeof(efs))
3105 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003106 break;
3107
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003108 case L2CAP_CONF_EWS:
3109 if (!enable_hs)
3110 return -ECONNREFUSED;
3111
3112 set_bit(FLAG_EXT_CTRL, &chan->flags);
3113 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003114 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003115 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003116 break;
3117
3118 default:
3119 if (hint)
3120 break;
3121
3122 result = L2CAP_CONF_UNKNOWN;
3123 *((u8 *) ptr++) = type;
3124 break;
3125 }
3126 }
3127
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003128 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003129 goto done;
3130
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003131 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003132 case L2CAP_MODE_STREAMING:
3133 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003134 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003135 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003136 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003137 break;
3138 }
3139
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003140 if (remote_efs) {
3141 if (__l2cap_efs_supported(chan))
3142 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3143 else
3144 return -ECONNREFUSED;
3145 }
3146
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003147 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003148 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003149
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003150 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003151 }
3152
3153done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003154 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003155 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003156 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003157
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003158 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003159 return -ECONNREFUSED;
3160
Gustavo Padovan2d792812012-10-06 10:07:01 +01003161 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3162 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003163 }
3164
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003165 if (result == L2CAP_CONF_SUCCESS) {
3166 /* Configure output options and let the other side know
3167 * which ones we don't like. */
3168
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003169 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3170 result = L2CAP_CONF_UNACCEPT;
3171 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003172 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003173 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003174 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003175 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003176
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003177 if (remote_efs) {
3178 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003179 efs.stype != L2CAP_SERV_NOTRAFIC &&
3180 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003181
3182 result = L2CAP_CONF_UNACCEPT;
3183
3184 if (chan->num_conf_req >= 1)
3185 return -ECONNREFUSED;
3186
3187 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003188 sizeof(efs),
3189 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003190 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003191 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003192 result = L2CAP_CONF_PENDING;
3193 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003194 }
3195 }
3196
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003197 switch (rfc.mode) {
3198 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003199 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003200 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003201 break;
3202
3203 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003204 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3205 chan->remote_tx_win = rfc.txwin_size;
3206 else
3207 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3208
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003209 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003210
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003211 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003212 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3213 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003214 rfc.max_pdu_size = cpu_to_le16(size);
3215 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003216
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003217 rfc.retrans_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003218 __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003219 rfc.monitor_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003220 __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003221
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003222 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003223
3224 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003225 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003226
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003227 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3228 chan->remote_id = efs.id;
3229 chan->remote_stype = efs.stype;
3230 chan->remote_msdu = le16_to_cpu(efs.msdu);
3231 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003232 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003233 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003234 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003235 chan->remote_sdu_itime =
3236 le32_to_cpu(efs.sdu_itime);
3237 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003238 sizeof(efs),
3239 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003240 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003241 break;
3242
3243 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003244 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003245 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3246 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003247 rfc.max_pdu_size = cpu_to_le16(size);
3248 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003249
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003250 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003251
Gustavo Padovan2d792812012-10-06 10:07:01 +01003252 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3253 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003254
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003255 break;
3256
3257 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003258 result = L2CAP_CONF_UNACCEPT;
3259
3260 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003261 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003262 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003263
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003264 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003265 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003266 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003267 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003268 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003269 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003270
3271 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003272}
3273
Gustavo Padovan2d792812012-10-06 10:07:01 +01003274static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3275 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003276{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003277 struct l2cap_conf_req *req = data;
3278 void *ptr = req->data;
3279 int type, olen;
3280 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003281 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003282 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003283
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003284 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003285
3286 while (len >= L2CAP_CONF_OPT_SIZE) {
3287 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3288
3289 switch (type) {
3290 case L2CAP_CONF_MTU:
3291 if (val < L2CAP_DEFAULT_MIN_MTU) {
3292 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003293 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003294 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003295 chan->imtu = val;
3296 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003297 break;
3298
3299 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003300 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003301 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003302 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003303 break;
3304
3305 case L2CAP_CONF_RFC:
3306 if (olen == sizeof(rfc))
3307 memcpy(&rfc, (void *)val, olen);
3308
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003309 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003310 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003311 return -ECONNREFUSED;
3312
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003313 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003314
3315 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003316 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003317 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003318
3319 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003320 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003321 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003322 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003323 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003324
3325 case L2CAP_CONF_EFS:
3326 if (olen == sizeof(efs))
3327 memcpy(&efs, (void *)val, olen);
3328
3329 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003330 efs.stype != L2CAP_SERV_NOTRAFIC &&
3331 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003332 return -ECONNREFUSED;
3333
Gustavo Padovan2d792812012-10-06 10:07:01 +01003334 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3335 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003336 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003337 }
3338 }
3339
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003340 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003341 return -ECONNREFUSED;
3342
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003343 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003344
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003345 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003346 switch (rfc.mode) {
3347 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003348 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3349 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3350 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003351 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3352 chan->ack_win = min_t(u16, chan->ack_win,
3353 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003354
3355 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3356 chan->local_msdu = le16_to_cpu(efs.msdu);
3357 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003358 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003359 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3360 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003361 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003362 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003363 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003364
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003365 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003366 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003367 }
3368 }
3369
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003370 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003371 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003372
3373 return ptr - data;
3374}
3375
Gustavo Padovan2d792812012-10-06 10:07:01 +01003376static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3377 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003378{
3379 struct l2cap_conf_rsp *rsp = data;
3380 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003381
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003382 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003383
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003384 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003385 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003386 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003387
3388 return ptr - data;
3389}
3390
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003391void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003392{
3393 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003394 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003395 u8 buf[128];
3396
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003397 rsp.scid = cpu_to_le16(chan->dcid);
3398 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003399 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3400 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo Padovan2d792812012-10-06 10:07:01 +01003401 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003402
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003403 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003404 return;
3405
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003406 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003407 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003408 chan->num_conf_req++;
3409}
3410
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003411static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003412{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003413 int type, olen;
3414 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003415 /* Use sane default values in case a misbehaving remote device
3416 * did not send an RFC or extended window size option.
3417 */
3418 u16 txwin_ext = chan->ack_win;
3419 struct l2cap_conf_rfc rfc = {
3420 .mode = chan->mode,
3421 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3422 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3423 .max_pdu_size = cpu_to_le16(chan->imtu),
3424 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3425 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003426
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003427 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003428
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003429 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003430 return;
3431
3432 while (len >= L2CAP_CONF_OPT_SIZE) {
3433 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3434
Mat Martineauc20f8e32012-07-10 05:47:07 -07003435 switch (type) {
3436 case L2CAP_CONF_RFC:
3437 if (olen == sizeof(rfc))
3438 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003439 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003440 case L2CAP_CONF_EWS:
3441 txwin_ext = val;
3442 break;
3443 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003444 }
3445
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003446 switch (rfc.mode) {
3447 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003448 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3449 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003450 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3451 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3452 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3453 else
3454 chan->ack_win = min_t(u16, chan->ack_win,
3455 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003456 break;
3457 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003458 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003459 }
3460}
3461
Gustavo Padovan2d792812012-10-06 10:07:01 +01003462static inline int l2cap_command_rej(struct l2cap_conn *conn,
3463 struct l2cap_cmd_hdr *cmd, u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003464{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003465 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003466
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003467 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003468 return 0;
3469
3470 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003471 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003472 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003473
3474 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003475 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003476
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003477 l2cap_conn_start(conn);
3478 }
3479
3480 return 0;
3481}
3482
Mat Martineau17009152012-10-23 15:24:07 -07003483static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3484 struct l2cap_cmd_hdr *cmd,
3485 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003486{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003487 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3488 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003489 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003490 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003491 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003492
3493 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003494 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003495
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003496 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003497
3498 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003499 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003500 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003501 result = L2CAP_CR_BAD_PSM;
3502 goto sendresp;
3503 }
3504
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003505 parent = pchan->sk;
3506
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003507 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003508 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003509
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003510 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003511 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003512 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003513 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003514 result = L2CAP_CR_SEC_BLOCK;
3515 goto response;
3516 }
3517
Linus Torvalds1da177e2005-04-16 15:20:36 -07003518 result = L2CAP_CR_NO_MEM;
3519
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003520 /* Check if we already have channel with that dcid */
3521 if (__l2cap_get_chan_by_dcid(conn, scid))
3522 goto response;
3523
Gustavo Padovan80b98022012-05-27 22:27:51 -03003524 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003525 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003526 goto response;
3527
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003528 sk = chan->sk;
3529
Linus Torvalds1da177e2005-04-16 15:20:36 -07003530 hci_conn_hold(conn->hcon);
3531
Linus Torvalds1da177e2005-04-16 15:20:36 -07003532 bacpy(&bt_sk(sk)->src, conn->src);
3533 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003534 chan->psm = psm;
3535 chan->dcid = scid;
Mat Martineau17009152012-10-23 15:24:07 -07003536 chan->local_amp_id = amp_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003537
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003538 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003539
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003540 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003541
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003542 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003543
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003544 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003545
Marcel Holtmann984947d2009-02-06 23:35:19 +01003546 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003547 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003548 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003549 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003550 result = L2CAP_CR_PEND;
3551 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003552 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003553 } else {
Mat Martineau17009152012-10-23 15:24:07 -07003554 /* Force pending result for AMP controllers.
3555 * The connection will succeed after the
3556 * physical link is up.
3557 */
3558 if (amp_id) {
3559 __l2cap_state_change(chan, BT_CONNECT2);
3560 result = L2CAP_CR_PEND;
3561 } else {
3562 __l2cap_state_change(chan, BT_CONFIG);
3563 result = L2CAP_CR_SUCCESS;
3564 }
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003565 status = L2CAP_CS_NO_INFO;
3566 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003567 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003568 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003569 result = L2CAP_CR_PEND;
3570 status = L2CAP_CS_AUTHEN_PEND;
3571 }
3572 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003573 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003574 result = L2CAP_CR_PEND;
3575 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003576 }
3577
Linus Torvalds1da177e2005-04-16 15:20:36 -07003578response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003579 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003580 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003581
3582sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003583 rsp.scid = cpu_to_le16(scid);
3584 rsp.dcid = cpu_to_le16(dcid);
3585 rsp.result = cpu_to_le16(result);
3586 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003587 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003588
3589 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3590 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003591 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003592
3593 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3594 conn->info_ident = l2cap_get_ident(conn);
3595
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003596 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003597
Gustavo Padovan2d792812012-10-06 10:07:01 +01003598 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3599 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003600 }
3601
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003602 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003603 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003604 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003605 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003606 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003607 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003608 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003609 }
Mat Martineau17009152012-10-23 15:24:07 -07003610
3611 return chan;
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003612}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003613
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003614static int l2cap_connect_req(struct l2cap_conn *conn,
3615 struct l2cap_cmd_hdr *cmd, u8 *data)
3616{
Gustavo Padovan300229f2012-10-12 19:40:40 +08003617 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003618 return 0;
3619}
3620
Mat Martineau5909cf32012-10-23 15:24:08 -07003621static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003622 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003623{
3624 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3625 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003626 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003627 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003628 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003629
3630 scid = __le16_to_cpu(rsp->scid);
3631 dcid = __le16_to_cpu(rsp->dcid);
3632 result = __le16_to_cpu(rsp->result);
3633 status = __le16_to_cpu(rsp->status);
3634
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003635 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 +01003636 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003637
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003638 mutex_lock(&conn->chan_lock);
3639
Linus Torvalds1da177e2005-04-16 15:20:36 -07003640 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003641 chan = __l2cap_get_chan_by_scid(conn, scid);
3642 if (!chan) {
3643 err = -EFAULT;
3644 goto unlock;
3645 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003646 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003647 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3648 if (!chan) {
3649 err = -EFAULT;
3650 goto unlock;
3651 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003652 }
3653
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003654 err = 0;
3655
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003656 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003657
Linus Torvalds1da177e2005-04-16 15:20:36 -07003658 switch (result) {
3659 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03003660 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003661 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003662 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003663 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003664
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003665 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003666 break;
3667
Linus Torvalds1da177e2005-04-16 15:20:36 -07003668 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003669 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003670 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003671 break;
3672
3673 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003674 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003675 break;
3676
3677 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003678 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003679 break;
3680 }
3681
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003682 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003683
3684unlock:
3685 mutex_unlock(&conn->chan_lock);
3686
3687 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003688}
3689
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003690static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003691{
3692 /* FCS is enabled only in ERTM or streaming mode, if one or both
3693 * sides request it.
3694 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003695 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003696 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003697 else if (!test_bit(CONF_NO_FCS_RECV, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003698 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003699}
3700
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003701static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3702 u8 ident, u16 flags)
3703{
3704 struct l2cap_conn *conn = chan->conn;
3705
3706 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3707 flags);
3708
3709 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3710 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3711
3712 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
3713 l2cap_build_conf_rsp(chan, data,
3714 L2CAP_CONF_SUCCESS, flags), data);
3715}
3716
Gustavo Padovan2d792812012-10-06 10:07:01 +01003717static inline int l2cap_config_req(struct l2cap_conn *conn,
3718 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3719 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003720{
3721 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3722 u16 dcid, flags;
3723 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003724 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003725 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003726
3727 dcid = __le16_to_cpu(req->dcid);
3728 flags = __le16_to_cpu(req->flags);
3729
3730 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3731
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003732 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003733 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003734 return -ENOENT;
3735
David S. Miller033b1142011-07-21 13:38:42 -07003736 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003737 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003738
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003739 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003740 rej.scid = cpu_to_le16(chan->scid);
3741 rej.dcid = cpu_to_le16(chan->dcid);
3742
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003743 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003744 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003745 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003746 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003747
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003748 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003749 len = cmd_len - sizeof(*req);
Dan Rosenberg7ac28812011-06-24 08:38:05 -04003750 if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003751 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003752 l2cap_build_conf_rsp(chan, rsp,
3753 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003754 goto unlock;
3755 }
3756
3757 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003758 memcpy(chan->conf_req + chan->conf_len, req->data, len);
3759 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003760
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003761 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003762 /* Incomplete config. Send empty response. */
3763 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003764 l2cap_build_conf_rsp(chan, rsp,
3765 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003766 goto unlock;
3767 }
3768
3769 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003770 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003771 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003772 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003773 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003774 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003775
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003776 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003777 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003778
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003779 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003780 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003781
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003782 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02003783 goto unlock;
3784
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003785 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003786 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003787
Mat Martineau105bdf92012-04-27 16:50:48 -07003788 if (chan->mode == L2CAP_MODE_ERTM ||
3789 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003790 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003791
Mat Martineau3c588192012-04-11 10:48:42 -07003792 if (err < 0)
3793 l2cap_send_disconn_req(chan->conn, chan, -err);
3794 else
3795 l2cap_chan_ready(chan);
3796
Marcel Holtmann876d9482007-10-20 13:35:42 +02003797 goto unlock;
3798 }
3799
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003800 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003801 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003802 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003803 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003804 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003805 }
3806
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003807 /* Got Conf Rsp PENDING from remote side and asume we sent
3808 Conf Rsp PENDING in the code above */
3809 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003810 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003811
3812 /* check compatibility */
3813
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03003814 /* Send rsp for BR/EDR channel */
3815 if (!chan->ctrl_id)
3816 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
3817 else
3818 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003819 }
3820
Linus Torvalds1da177e2005-04-16 15:20:36 -07003821unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003822 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003823 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003824}
3825
Gustavo Padovan2d792812012-10-06 10:07:01 +01003826static inline int l2cap_config_rsp(struct l2cap_conn *conn,
3827 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003828{
3829 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3830 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003831 struct l2cap_chan *chan;
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003832 int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07003833 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003834
3835 scid = __le16_to_cpu(rsp->scid);
3836 flags = __le16_to_cpu(rsp->flags);
3837 result = __le16_to_cpu(rsp->result);
3838
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003839 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
3840 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003841
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003842 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003843 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003844 return 0;
3845
3846 switch (result) {
3847 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003848 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003849 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003850 break;
3851
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003852 case L2CAP_CONF_PENDING:
3853 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
3854
3855 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3856 char buf[64];
3857
3858 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003859 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003860 if (len < 0) {
3861 l2cap_send_disconn_req(conn, chan, ECONNRESET);
3862 goto done;
3863 }
3864
3865 /* check compatibility */
3866
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03003867 if (!chan->ctrl_id)
3868 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
3869 0);
3870 else
3871 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003872 }
3873 goto done;
3874
Linus Torvalds1da177e2005-04-16 15:20:36 -07003875 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003876 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003877 char req[64];
3878
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003879 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003880 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003881 goto done;
3882 }
3883
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003884 /* throw out any old stored conf requests */
3885 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003886 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003887 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003888 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003889 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003890 goto done;
3891 }
3892
3893 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003894 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003895 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003896 if (result != L2CAP_CONF_SUCCESS)
3897 goto done;
3898 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003899 }
3900
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003901 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003902 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02003903
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003904 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003905 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003906 goto done;
3907 }
3908
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003909 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003910 goto done;
3911
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003912 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003913
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003914 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003915 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003916
Mat Martineau105bdf92012-04-27 16:50:48 -07003917 if (chan->mode == L2CAP_MODE_ERTM ||
3918 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003919 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003920
Mat Martineau3c588192012-04-11 10:48:42 -07003921 if (err < 0)
3922 l2cap_send_disconn_req(chan->conn, chan, -err);
3923 else
3924 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003925 }
3926
3927done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003928 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003929 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003930}
3931
Gustavo Padovan2d792812012-10-06 10:07:01 +01003932static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
3933 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003934{
3935 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3936 struct l2cap_disconn_rsp rsp;
3937 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003938 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003939 struct sock *sk;
3940
3941 scid = __le16_to_cpu(req->scid);
3942 dcid = __le16_to_cpu(req->dcid);
3943
3944 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3945
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003946 mutex_lock(&conn->chan_lock);
3947
3948 chan = __l2cap_get_chan_by_scid(conn, dcid);
3949 if (!chan) {
3950 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003951 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003952 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003953
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003954 l2cap_chan_lock(chan);
3955
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003956 sk = chan->sk;
3957
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003958 rsp.dcid = cpu_to_le16(chan->scid);
3959 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003960 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3961
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003962 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003963 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003964 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003965
Mat Martineau61d6ef32012-04-27 16:50:50 -07003966 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003967 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003968
3969 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003970
Gustavo Padovan80b98022012-05-27 22:27:51 -03003971 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003972 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003973
3974 mutex_unlock(&conn->chan_lock);
3975
Linus Torvalds1da177e2005-04-16 15:20:36 -07003976 return 0;
3977}
3978
Gustavo Padovan2d792812012-10-06 10:07:01 +01003979static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
3980 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003981{
3982 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3983 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003984 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003985
3986 scid = __le16_to_cpu(rsp->scid);
3987 dcid = __le16_to_cpu(rsp->dcid);
3988
3989 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3990
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003991 mutex_lock(&conn->chan_lock);
3992
3993 chan = __l2cap_get_chan_by_scid(conn, scid);
3994 if (!chan) {
3995 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003996 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003997 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003998
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003999 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004000
Mat Martineau61d6ef32012-04-27 16:50:50 -07004001 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03004002 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02004003
4004 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004005
Gustavo Padovan80b98022012-05-27 22:27:51 -03004006 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07004007 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02004008
4009 mutex_unlock(&conn->chan_lock);
4010
Linus Torvalds1da177e2005-04-16 15:20:36 -07004011 return 0;
4012}
4013
Gustavo Padovan2d792812012-10-06 10:07:01 +01004014static inline int l2cap_information_req(struct l2cap_conn *conn,
4015 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004016{
4017 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004018 u16 type;
4019
4020 type = __le16_to_cpu(req->type);
4021
4022 BT_DBG("type 0x%4.4x", type);
4023
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004024 if (type == L2CAP_IT_FEAT_MASK) {
4025 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07004026 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004027 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004028 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
4029 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03004030 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004031 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01004032 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004033 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03004034 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01004035 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03004036
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03004037 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004038 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4039 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004040 } else if (type == L2CAP_IT_FIXED_CHAN) {
4041 u8 buf[12];
4042 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07004043
4044 if (enable_hs)
4045 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
4046 else
4047 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
4048
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004049 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4050 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03004051 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01004052 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
4053 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004054 } else {
4055 struct l2cap_info_rsp rsp;
4056 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004057 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004058 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
4059 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02004060 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004061
4062 return 0;
4063}
4064
Gustavo Padovan2d792812012-10-06 10:07:01 +01004065static inline int l2cap_information_rsp(struct l2cap_conn *conn,
4066 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004067{
4068 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4069 u16 type, result;
4070
4071 type = __le16_to_cpu(rsp->type);
4072 result = __le16_to_cpu(rsp->result);
4073
4074 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
4075
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004076 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
4077 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01004078 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02004079 return 0;
4080
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02004081 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004082
Ville Tervoadb08ed2010-08-04 09:43:33 +03004083 if (result != L2CAP_IR_SUCCESS) {
4084 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4085 conn->info_ident = 0;
4086
4087 l2cap_conn_start(conn);
4088
4089 return 0;
4090 }
4091
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004092 switch (type) {
4093 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07004094 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004095
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07004096 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004097 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004098 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004099
4100 conn->info_ident = l2cap_get_ident(conn);
4101
4102 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004103 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004104 } else {
4105 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4106 conn->info_ident = 0;
4107
4108 l2cap_conn_start(conn);
4109 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004110 break;
4111
4112 case L2CAP_IT_FIXED_CHAN:
4113 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004114 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004115 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004116
4117 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004118 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004119 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004120
Linus Torvalds1da177e2005-04-16 15:20:36 -07004121 return 0;
4122}
4123
Mat Martineau17009152012-10-23 15:24:07 -07004124static int l2cap_create_channel_req(struct l2cap_conn *conn,
4125 struct l2cap_cmd_hdr *cmd,
4126 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004127{
4128 struct l2cap_create_chan_req *req = data;
Mat Martineau17009152012-10-23 15:24:07 -07004129 struct l2cap_chan *chan;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004130 u16 psm, scid;
4131
4132 if (cmd_len != sizeof(*req))
4133 return -EPROTO;
4134
4135 if (!enable_hs)
4136 return -EINVAL;
4137
4138 psm = le16_to_cpu(req->psm);
4139 scid = le16_to_cpu(req->scid);
4140
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004141 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 -07004142
Mat Martineau17009152012-10-23 15:24:07 -07004143 if (req->amp_id) {
4144 struct hci_dev *hdev;
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004145
Mat Martineau17009152012-10-23 15:24:07 -07004146 /* Validate AMP controller id */
4147 hdev = hci_dev_get(req->amp_id);
4148 if (!hdev || hdev->dev_type != HCI_AMP ||
4149 !test_bit(HCI_UP, &hdev->flags)) {
4150 struct l2cap_create_chan_rsp rsp;
4151
4152 rsp.dcid = 0;
4153 rsp.scid = cpu_to_le16(scid);
4154 rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
4155 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
4156
4157 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4158 sizeof(rsp), &rsp);
4159
4160 if (hdev)
4161 hci_dev_put(hdev);
4162
4163 return 0;
4164 }
4165
4166 hci_dev_put(hdev);
4167 }
4168
4169 chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
4170 req->amp_id);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004171
4172 return 0;
4173}
4174
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004175static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004176 u16 icid, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004177{
4178 struct l2cap_move_chan_rsp rsp;
4179
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004180 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004181
4182 rsp.icid = cpu_to_le16(icid);
4183 rsp.result = cpu_to_le16(result);
4184
4185 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_RSP, sizeof(rsp), &rsp);
4186}
4187
4188static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004189 struct l2cap_chan *chan,
4190 u16 icid, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004191{
4192 struct l2cap_move_chan_cfm cfm;
4193 u8 ident;
4194
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004195 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004196
4197 ident = l2cap_get_ident(conn);
4198 if (chan)
4199 chan->ident = ident;
4200
4201 cfm.icid = cpu_to_le16(icid);
4202 cfm.result = cpu_to_le16(result);
4203
4204 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM, sizeof(cfm), &cfm);
4205}
4206
4207static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004208 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004209{
4210 struct l2cap_move_chan_cfm_rsp rsp;
4211
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004212 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004213
4214 rsp.icid = cpu_to_le16(icid);
4215 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4216}
4217
Mat Martineau5f3847a2012-10-23 15:24:12 -07004218static void __release_logical_link(struct l2cap_chan *chan)
4219{
4220 chan->hs_hchan = NULL;
4221 chan->hs_hcon = NULL;
4222
4223 /* Placeholder - release the logical link */
4224}
4225
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004226static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004227 struct l2cap_cmd_hdr *cmd,
4228 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004229{
4230 struct l2cap_move_chan_req *req = data;
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004231 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004232 u16 icid = 0;
4233 u16 result = L2CAP_MR_NOT_ALLOWED;
4234
4235 if (cmd_len != sizeof(*req))
4236 return -EPROTO;
4237
4238 icid = le16_to_cpu(req->icid);
4239
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004240 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004241
4242 if (!enable_hs)
4243 return -EINVAL;
4244
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004245 chan = l2cap_get_chan_by_dcid(conn, icid);
4246 if (!chan) {
4247 l2cap_send_move_chan_rsp(conn, cmd->ident, icid,
4248 L2CAP_MR_NOT_ALLOWED);
4249 return 0;
4250 }
4251
4252 if (chan->scid < L2CAP_CID_DYN_START ||
4253 chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY ||
4254 (chan->mode != L2CAP_MODE_ERTM &&
4255 chan->mode != L2CAP_MODE_STREAMING)) {
4256 result = L2CAP_MR_NOT_ALLOWED;
4257 goto send_move_response;
4258 }
4259
4260 if (chan->local_amp_id == req->dest_amp_id) {
4261 result = L2CAP_MR_SAME_ID;
4262 goto send_move_response;
4263 }
4264
4265 if (req->dest_amp_id) {
4266 struct hci_dev *hdev;
4267 hdev = hci_dev_get(req->dest_amp_id);
4268 if (!hdev || hdev->dev_type != HCI_AMP ||
4269 !test_bit(HCI_UP, &hdev->flags)) {
4270 if (hdev)
4271 hci_dev_put(hdev);
4272
4273 result = L2CAP_MR_BAD_ID;
4274 goto send_move_response;
4275 }
4276 hci_dev_put(hdev);
4277 }
4278
4279 /* Detect a move collision. Only send a collision response
4280 * if this side has "lost", otherwise proceed with the move.
4281 * The winner has the larger bd_addr.
4282 */
4283 if ((__chan_is_moving(chan) ||
4284 chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
4285 bacmp(conn->src, conn->dst) > 0) {
4286 result = L2CAP_MR_COLLISION;
4287 goto send_move_response;
4288 }
4289
4290 chan->ident = cmd->ident;
4291 chan->move_role = L2CAP_MOVE_ROLE_RESPONDER;
4292 l2cap_move_setup(chan);
4293 chan->move_id = req->dest_amp_id;
4294 icid = chan->dcid;
4295
4296 if (!req->dest_amp_id) {
4297 /* Moving to BR/EDR */
4298 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4299 chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
4300 result = L2CAP_MR_PEND;
4301 } else {
4302 chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
4303 result = L2CAP_MR_SUCCESS;
4304 }
4305 } else {
4306 chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
4307 /* Placeholder - uncomment when amp functions are available */
4308 /*amp_accept_physical(chan, req->dest_amp_id);*/
4309 result = L2CAP_MR_PEND;
4310 }
4311
4312send_move_response:
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004313 l2cap_send_move_chan_rsp(conn, cmd->ident, icid, result);
4314
Mat Martineau02b0fbb2012-10-23 15:24:10 -07004315 l2cap_chan_unlock(chan);
4316
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004317 return 0;
4318}
4319
4320static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004321 struct l2cap_cmd_hdr *cmd,
4322 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004323{
4324 struct l2cap_move_chan_rsp *rsp = data;
4325 u16 icid, result;
4326
4327 if (cmd_len != sizeof(*rsp))
4328 return -EPROTO;
4329
4330 icid = le16_to_cpu(rsp->icid);
4331 result = le16_to_cpu(rsp->result);
4332
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004333 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004334
4335 /* Placeholder: Always unconfirmed */
4336 l2cap_send_move_chan_cfm(conn, NULL, icid, L2CAP_MC_UNCONFIRMED);
4337
4338 return 0;
4339}
4340
Mat Martineau5f3847a2012-10-23 15:24:12 -07004341static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
4342 struct l2cap_cmd_hdr *cmd,
4343 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004344{
4345 struct l2cap_move_chan_cfm *cfm = data;
Mat Martineau5f3847a2012-10-23 15:24:12 -07004346 struct l2cap_chan *chan;
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004347 u16 icid, result;
4348
4349 if (cmd_len != sizeof(*cfm))
4350 return -EPROTO;
4351
4352 icid = le16_to_cpu(cfm->icid);
4353 result = le16_to_cpu(cfm->result);
4354
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004355 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004356
Mat Martineau5f3847a2012-10-23 15:24:12 -07004357 chan = l2cap_get_chan_by_dcid(conn, icid);
4358 if (!chan) {
4359 /* Spec requires a response even if the icid was not found */
4360 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4361 return 0;
4362 }
4363
4364 if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
4365 if (result == L2CAP_MC_CONFIRMED) {
4366 chan->local_amp_id = chan->move_id;
4367 if (!chan->local_amp_id)
4368 __release_logical_link(chan);
4369 } else {
4370 chan->move_id = chan->local_amp_id;
4371 }
4372
4373 l2cap_move_done(chan);
4374 }
4375
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004376 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4377
Mat Martineau5f3847a2012-10-23 15:24:12 -07004378 l2cap_chan_unlock(chan);
4379
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004380 return 0;
4381}
4382
4383static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004384 struct l2cap_cmd_hdr *cmd,
4385 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004386{
4387 struct l2cap_move_chan_cfm_rsp *rsp = data;
4388 u16 icid;
4389
4390 if (cmd_len != sizeof(*rsp))
4391 return -EPROTO;
4392
4393 icid = le16_to_cpu(rsp->icid);
4394
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004395 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004396
4397 return 0;
4398}
4399
Gustavo F. Padovane2174ca42011-02-17 19:16:55 -03004400static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004401 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02004402{
4403 u16 max_latency;
4404
4405 if (min > max || min < 6 || max > 3200)
4406 return -EINVAL;
4407
4408 if (to_multiplier < 10 || to_multiplier > 3200)
4409 return -EINVAL;
4410
4411 if (max >= to_multiplier * 8)
4412 return -EINVAL;
4413
4414 max_latency = (to_multiplier * 8 / max) - 1;
4415 if (latency > 499 || latency > max_latency)
4416 return -EINVAL;
4417
4418 return 0;
4419}
4420
4421static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004422 struct l2cap_cmd_hdr *cmd,
4423 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02004424{
4425 struct hci_conn *hcon = conn->hcon;
4426 struct l2cap_conn_param_update_req *req;
4427 struct l2cap_conn_param_update_rsp rsp;
4428 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004429 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02004430
4431 if (!(hcon->link_mode & HCI_LM_MASTER))
4432 return -EINVAL;
4433
4434 cmd_len = __le16_to_cpu(cmd->len);
4435 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
4436 return -EPROTO;
4437
4438 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca42011-02-17 19:16:55 -03004439 min = __le16_to_cpu(req->min);
4440 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02004441 latency = __le16_to_cpu(req->latency);
4442 to_multiplier = __le16_to_cpu(req->to_multiplier);
4443
4444 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 +01004445 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02004446
4447 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004448
4449 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
4450 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004451 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004452 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004453 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004454
4455 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004456 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02004457
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004458 if (!err)
4459 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
4460
Claudio Takahaside731152011-02-11 19:28:55 -02004461 return 0;
4462}
4463
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004464static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004465 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4466 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004467{
4468 int err = 0;
4469
4470 switch (cmd->code) {
4471 case L2CAP_COMMAND_REJ:
4472 l2cap_command_rej(conn, cmd, data);
4473 break;
4474
4475 case L2CAP_CONN_REQ:
4476 err = l2cap_connect_req(conn, cmd, data);
4477 break;
4478
4479 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03004480 case L2CAP_CREATE_CHAN_RSP:
Mat Martineau5909cf32012-10-23 15:24:08 -07004481 err = l2cap_connect_create_rsp(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004482 break;
4483
4484 case L2CAP_CONF_REQ:
4485 err = l2cap_config_req(conn, cmd, cmd_len, data);
4486 break;
4487
4488 case L2CAP_CONF_RSP:
4489 err = l2cap_config_rsp(conn, cmd, data);
4490 break;
4491
4492 case L2CAP_DISCONN_REQ:
4493 err = l2cap_disconnect_req(conn, cmd, data);
4494 break;
4495
4496 case L2CAP_DISCONN_RSP:
4497 err = l2cap_disconnect_rsp(conn, cmd, data);
4498 break;
4499
4500 case L2CAP_ECHO_REQ:
4501 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
4502 break;
4503
4504 case L2CAP_ECHO_RSP:
4505 break;
4506
4507 case L2CAP_INFO_REQ:
4508 err = l2cap_information_req(conn, cmd, data);
4509 break;
4510
4511 case L2CAP_INFO_RSP:
4512 err = l2cap_information_rsp(conn, cmd, data);
4513 break;
4514
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004515 case L2CAP_CREATE_CHAN_REQ:
4516 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
4517 break;
4518
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004519 case L2CAP_MOVE_CHAN_REQ:
4520 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
4521 break;
4522
4523 case L2CAP_MOVE_CHAN_RSP:
4524 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
4525 break;
4526
4527 case L2CAP_MOVE_CHAN_CFM:
4528 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
4529 break;
4530
4531 case L2CAP_MOVE_CHAN_CFM_RSP:
4532 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
4533 break;
4534
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004535 default:
4536 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
4537 err = -EINVAL;
4538 break;
4539 }
4540
4541 return err;
4542}
4543
4544static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004545 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004546{
4547 switch (cmd->code) {
4548 case L2CAP_COMMAND_REJ:
4549 return 0;
4550
4551 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02004552 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004553
4554 case L2CAP_CONN_PARAM_UPDATE_RSP:
4555 return 0;
4556
4557 default:
4558 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
4559 return -EINVAL;
4560 }
4561}
4562
4563static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004564 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004565{
4566 u8 *data = skb->data;
4567 int len = skb->len;
4568 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004569 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004570
4571 l2cap_raw_recv(conn, skb);
4572
4573 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07004574 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004575 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
4576 data += L2CAP_CMD_HDR_SIZE;
4577 len -= L2CAP_CMD_HDR_SIZE;
4578
Al Viro88219a02007-07-29 00:17:25 -07004579 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004580
Gustavo Padovan2d792812012-10-06 10:07:01 +01004581 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
4582 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004583
Al Viro88219a02007-07-29 00:17:25 -07004584 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004585 BT_DBG("corrupted command");
4586 break;
4587 }
4588
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004589 if (conn->hcon->type == LE_LINK)
4590 err = l2cap_le_sig_cmd(conn, &cmd, data);
4591 else
4592 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004593
4594 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004595 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03004596
4597 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004598
4599 /* FIXME: Map err to a valid reason */
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004600 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004601 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
4602 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004603 }
4604
Al Viro88219a02007-07-29 00:17:25 -07004605 data += cmd_len;
4606 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004607 }
4608
4609 kfree_skb(skb);
4610}
4611
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004612static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004613{
4614 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03004615 int hdr_size;
4616
4617 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
4618 hdr_size = L2CAP_EXT_HDR_SIZE;
4619 else
4620 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004621
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004622 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004623 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004624 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
4625 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
4626
4627 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03004628 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004629 }
4630 return 0;
4631}
4632
Mat Martineau6ea00482012-05-17 20:53:52 -07004633static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004634{
Mat Martineaue31f7632012-05-17 20:53:41 -07004635 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004636
Mat Martineaue31f7632012-05-17 20:53:41 -07004637 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004638
Mat Martineaue31f7632012-05-17 20:53:41 -07004639 memset(&control, 0, sizeof(control));
4640 control.sframe = 1;
4641 control.final = 1;
4642 control.reqseq = chan->buffer_seq;
4643 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004644
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004645 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07004646 control.super = L2CAP_SUPER_RNR;
4647 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004648 }
4649
Mat Martineaue31f7632012-05-17 20:53:41 -07004650 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
4651 chan->unacked_frames > 0)
4652 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004653
Mat Martineaue31f7632012-05-17 20:53:41 -07004654 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03004655 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004656
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004657 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07004658 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
4659 /* F-bit wasn't sent in an s-frame or i-frame yet, so
4660 * send it now.
4661 */
4662 control.super = L2CAP_SUPER_RR;
4663 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004664 }
4665}
4666
Gustavo Padovan2d792812012-10-06 10:07:01 +01004667static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
4668 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004669{
Mat Martineau84084a32011-07-22 14:54:00 -07004670 /* skb->len reflects data in skb as well as all fragments
4671 * skb->data_len reflects only data in fragments
4672 */
4673 if (!skb_has_frag_list(skb))
4674 skb_shinfo(skb)->frag_list = new_frag;
4675
4676 new_frag->next = NULL;
4677
4678 (*last_frag)->next = new_frag;
4679 *last_frag = new_frag;
4680
4681 skb->len += new_frag->len;
4682 skb->data_len += new_frag->len;
4683 skb->truesize += new_frag->truesize;
4684}
4685
Mat Martineau4b51dae92012-05-17 20:53:37 -07004686static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
4687 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07004688{
4689 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004690
Mat Martineau4b51dae92012-05-17 20:53:37 -07004691 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004692 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07004693 if (chan->sdu)
4694 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004695
Gustavo Padovan80b98022012-05-27 22:27:51 -03004696 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07004697 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004698
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004699 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07004700 if (chan->sdu)
4701 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004702
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004703 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004704 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004705
Mat Martineau84084a32011-07-22 14:54:00 -07004706 if (chan->sdu_len > chan->imtu) {
4707 err = -EMSGSIZE;
4708 break;
4709 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004710
Mat Martineau84084a32011-07-22 14:54:00 -07004711 if (skb->len >= chan->sdu_len)
4712 break;
4713
4714 chan->sdu = skb;
4715 chan->sdu_last_frag = skb;
4716
4717 skb = NULL;
4718 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004719 break;
4720
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004721 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004722 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004723 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004724
Mat Martineau84084a32011-07-22 14:54:00 -07004725 append_skb_frag(chan->sdu, skb,
4726 &chan->sdu_last_frag);
4727 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004728
Mat Martineau84084a32011-07-22 14:54:00 -07004729 if (chan->sdu->len >= chan->sdu_len)
4730 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004731
Mat Martineau84084a32011-07-22 14:54:00 -07004732 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004733 break;
4734
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004735 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004736 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004737 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004738
Mat Martineau84084a32011-07-22 14:54:00 -07004739 append_skb_frag(chan->sdu, skb,
4740 &chan->sdu_last_frag);
4741 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004742
Mat Martineau84084a32011-07-22 14:54:00 -07004743 if (chan->sdu->len != chan->sdu_len)
4744 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004745
Gustavo Padovan80b98022012-05-27 22:27:51 -03004746 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004747
Mat Martineau84084a32011-07-22 14:54:00 -07004748 if (!err) {
4749 /* Reassembly complete */
4750 chan->sdu = NULL;
4751 chan->sdu_last_frag = NULL;
4752 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004753 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004754 break;
4755 }
4756
Mat Martineau84084a32011-07-22 14:54:00 -07004757 if (err) {
4758 kfree_skb(skb);
4759 kfree_skb(chan->sdu);
4760 chan->sdu = NULL;
4761 chan->sdu_last_frag = NULL;
4762 chan->sdu_len = 0;
4763 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004764
Mat Martineau84084a32011-07-22 14:54:00 -07004765 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004766}
4767
Mat Martineau32b32732012-10-23 15:24:11 -07004768static int l2cap_resegment(struct l2cap_chan *chan)
4769{
4770 /* Placeholder */
4771 return 0;
4772}
4773
Mat Martineaue3281402011-07-07 09:39:02 -07004774void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132eb2010-06-21 19:39:50 -03004775{
Mat Martineau61aa4f52012-05-17 20:53:40 -07004776 u8 event;
4777
4778 if (chan->mode != L2CAP_MODE_ERTM)
4779 return;
4780
4781 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03004782 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004783}
4784
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004785static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
4786{
Mat Martineau63838722012-05-17 20:53:45 -07004787 int err = 0;
4788 /* Pass sequential frames to l2cap_reassemble_sdu()
4789 * until a gap is encountered.
4790 */
4791
4792 BT_DBG("chan %p", chan);
4793
4794 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4795 struct sk_buff *skb;
4796 BT_DBG("Searching for skb with txseq %d (queue len %d)",
4797 chan->buffer_seq, skb_queue_len(&chan->srej_q));
4798
4799 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
4800
4801 if (!skb)
4802 break;
4803
4804 skb_unlink(skb, &chan->srej_q);
4805 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
4806 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
4807 if (err)
4808 break;
4809 }
4810
4811 if (skb_queue_empty(&chan->srej_q)) {
4812 chan->rx_state = L2CAP_RX_STATE_RECV;
4813 l2cap_send_ack(chan);
4814 }
4815
4816 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004817}
4818
4819static void l2cap_handle_srej(struct l2cap_chan *chan,
4820 struct l2cap_ctrl *control)
4821{
Mat Martineauf80842a2012-05-17 20:53:46 -07004822 struct sk_buff *skb;
4823
4824 BT_DBG("chan %p, control %p", chan, control);
4825
4826 if (control->reqseq == chan->next_tx_seq) {
4827 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4828 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4829 return;
4830 }
4831
4832 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4833
4834 if (skb == NULL) {
4835 BT_DBG("Seq %d not available for retransmission",
4836 control->reqseq);
4837 return;
4838 }
4839
4840 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
4841 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4842 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4843 return;
4844 }
4845
4846 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4847
4848 if (control->poll) {
4849 l2cap_pass_to_tx(chan, control);
4850
4851 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4852 l2cap_retransmit(chan, control);
4853 l2cap_ertm_send(chan);
4854
4855 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4856 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4857 chan->srej_save_reqseq = control->reqseq;
4858 }
4859 } else {
4860 l2cap_pass_to_tx_fbit(chan, control);
4861
4862 if (control->final) {
4863 if (chan->srej_save_reqseq != control->reqseq ||
4864 !test_and_clear_bit(CONN_SREJ_ACT,
4865 &chan->conn_state))
4866 l2cap_retransmit(chan, control);
4867 } else {
4868 l2cap_retransmit(chan, control);
4869 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4870 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4871 chan->srej_save_reqseq = control->reqseq;
4872 }
4873 }
4874 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004875}
4876
4877static void l2cap_handle_rej(struct l2cap_chan *chan,
4878 struct l2cap_ctrl *control)
4879{
Mat Martineaufcd289d2012-05-17 20:53:47 -07004880 struct sk_buff *skb;
4881
4882 BT_DBG("chan %p, control %p", chan, control);
4883
4884 if (control->reqseq == chan->next_tx_seq) {
4885 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4886 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4887 return;
4888 }
4889
4890 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4891
4892 if (chan->max_tx && skb &&
4893 bt_cb(skb)->control.retries >= chan->max_tx) {
4894 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4895 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4896 return;
4897 }
4898
4899 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4900
4901 l2cap_pass_to_tx(chan, control);
4902
4903 if (control->final) {
4904 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
4905 l2cap_retransmit_all(chan, control);
4906 } else {
4907 l2cap_retransmit_all(chan, control);
4908 l2cap_ertm_send(chan);
4909 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
4910 set_bit(CONN_REJ_ACT, &chan->conn_state);
4911 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004912}
4913
Mat Martineau4b51dae92012-05-17 20:53:37 -07004914static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
4915{
4916 BT_DBG("chan %p, txseq %d", chan, txseq);
4917
4918 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
4919 chan->expected_tx_seq);
4920
4921 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
4922 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01004923 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07004924 /* See notes below regarding "double poll" and
4925 * invalid packets.
4926 */
4927 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4928 BT_DBG("Invalid/Ignore - after SREJ");
4929 return L2CAP_TXSEQ_INVALID_IGNORE;
4930 } else {
4931 BT_DBG("Invalid - in window after SREJ sent");
4932 return L2CAP_TXSEQ_INVALID;
4933 }
4934 }
4935
4936 if (chan->srej_list.head == txseq) {
4937 BT_DBG("Expected SREJ");
4938 return L2CAP_TXSEQ_EXPECTED_SREJ;
4939 }
4940
4941 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
4942 BT_DBG("Duplicate SREJ - txseq already stored");
4943 return L2CAP_TXSEQ_DUPLICATE_SREJ;
4944 }
4945
4946 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
4947 BT_DBG("Unexpected SREJ - not requested");
4948 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
4949 }
4950 }
4951
4952 if (chan->expected_tx_seq == txseq) {
4953 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4954 chan->tx_win) {
4955 BT_DBG("Invalid - txseq outside tx window");
4956 return L2CAP_TXSEQ_INVALID;
4957 } else {
4958 BT_DBG("Expected");
4959 return L2CAP_TXSEQ_EXPECTED;
4960 }
4961 }
4962
4963 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01004964 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07004965 BT_DBG("Duplicate - expected_tx_seq later than txseq");
4966 return L2CAP_TXSEQ_DUPLICATE;
4967 }
4968
4969 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
4970 /* A source of invalid packets is a "double poll" condition,
4971 * where delays cause us to send multiple poll packets. If
4972 * the remote stack receives and processes both polls,
4973 * sequence numbers can wrap around in such a way that a
4974 * resent frame has a sequence number that looks like new data
4975 * with a sequence gap. This would trigger an erroneous SREJ
4976 * request.
4977 *
4978 * Fortunately, this is impossible with a tx window that's
4979 * less than half of the maximum sequence number, which allows
4980 * invalid frames to be safely ignored.
4981 *
4982 * With tx window sizes greater than half of the tx window
4983 * maximum, the frame is invalid and cannot be ignored. This
4984 * causes a disconnect.
4985 */
4986
4987 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4988 BT_DBG("Invalid/Ignore - txseq outside tx window");
4989 return L2CAP_TXSEQ_INVALID_IGNORE;
4990 } else {
4991 BT_DBG("Invalid - txseq outside tx window");
4992 return L2CAP_TXSEQ_INVALID;
4993 }
4994 } else {
4995 BT_DBG("Unexpected - txseq indicates missing frames");
4996 return L2CAP_TXSEQ_UNEXPECTED;
4997 }
4998}
4999
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005000static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5001 struct l2cap_ctrl *control,
5002 struct sk_buff *skb, u8 event)
5003{
5004 int err = 0;
5005 bool skb_in_use = 0;
5006
5007 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5008 event);
5009
5010 switch (event) {
5011 case L2CAP_EV_RECV_IFRAME:
5012 switch (l2cap_classify_txseq(chan, control->txseq)) {
5013 case L2CAP_TXSEQ_EXPECTED:
5014 l2cap_pass_to_tx(chan, control);
5015
5016 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5017 BT_DBG("Busy, discarding expected seq %d",
5018 control->txseq);
5019 break;
5020 }
5021
5022 chan->expected_tx_seq = __next_seq(chan,
5023 control->txseq);
5024
5025 chan->buffer_seq = chan->expected_tx_seq;
5026 skb_in_use = 1;
5027
5028 err = l2cap_reassemble_sdu(chan, skb, control);
5029 if (err)
5030 break;
5031
5032 if (control->final) {
5033 if (!test_and_clear_bit(CONN_REJ_ACT,
5034 &chan->conn_state)) {
5035 control->final = 0;
5036 l2cap_retransmit_all(chan, control);
5037 l2cap_ertm_send(chan);
5038 }
5039 }
5040
5041 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5042 l2cap_send_ack(chan);
5043 break;
5044 case L2CAP_TXSEQ_UNEXPECTED:
5045 l2cap_pass_to_tx(chan, control);
5046
5047 /* Can't issue SREJ frames in the local busy state.
5048 * Drop this frame, it will be seen as missing
5049 * when local busy is exited.
5050 */
5051 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5052 BT_DBG("Busy, discarding unexpected seq %d",
5053 control->txseq);
5054 break;
5055 }
5056
5057 /* There was a gap in the sequence, so an SREJ
5058 * must be sent for each missing frame. The
5059 * current frame is stored for later use.
5060 */
5061 skb_queue_tail(&chan->srej_q, skb);
5062 skb_in_use = 1;
5063 BT_DBG("Queued %p (queue len %d)", skb,
5064 skb_queue_len(&chan->srej_q));
5065
5066 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5067 l2cap_seq_list_clear(&chan->srej_list);
5068 l2cap_send_srej(chan, control->txseq);
5069
5070 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5071 break;
5072 case L2CAP_TXSEQ_DUPLICATE:
5073 l2cap_pass_to_tx(chan, control);
5074 break;
5075 case L2CAP_TXSEQ_INVALID_IGNORE:
5076 break;
5077 case L2CAP_TXSEQ_INVALID:
5078 default:
5079 l2cap_send_disconn_req(chan->conn, chan,
5080 ECONNRESET);
5081 break;
5082 }
5083 break;
5084 case L2CAP_EV_RECV_RR:
5085 l2cap_pass_to_tx(chan, control);
5086 if (control->final) {
5087 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5088
5089 if (!test_and_clear_bit(CONN_REJ_ACT,
5090 &chan->conn_state)) {
5091 control->final = 0;
5092 l2cap_retransmit_all(chan, control);
5093 }
5094
5095 l2cap_ertm_send(chan);
5096 } else if (control->poll) {
5097 l2cap_send_i_or_rr_or_rnr(chan);
5098 } else {
5099 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5100 &chan->conn_state) &&
5101 chan->unacked_frames)
5102 __set_retrans_timer(chan);
5103
5104 l2cap_ertm_send(chan);
5105 }
5106 break;
5107 case L2CAP_EV_RECV_RNR:
5108 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5109 l2cap_pass_to_tx(chan, control);
5110 if (control && control->poll) {
5111 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5112 l2cap_send_rr_or_rnr(chan, 0);
5113 }
5114 __clear_retrans_timer(chan);
5115 l2cap_seq_list_clear(&chan->retrans_list);
5116 break;
5117 case L2CAP_EV_RECV_REJ:
5118 l2cap_handle_rej(chan, control);
5119 break;
5120 case L2CAP_EV_RECV_SREJ:
5121 l2cap_handle_srej(chan, control);
5122 break;
5123 default:
5124 break;
5125 }
5126
5127 if (skb && !skb_in_use) {
5128 BT_DBG("Freeing %p", skb);
5129 kfree_skb(skb);
5130 }
5131
5132 return err;
5133}
5134
5135static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5136 struct l2cap_ctrl *control,
5137 struct sk_buff *skb, u8 event)
5138{
5139 int err = 0;
5140 u16 txseq = control->txseq;
5141 bool skb_in_use = 0;
5142
5143 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5144 event);
5145
5146 switch (event) {
5147 case L2CAP_EV_RECV_IFRAME:
5148 switch (l2cap_classify_txseq(chan, txseq)) {
5149 case L2CAP_TXSEQ_EXPECTED:
5150 /* Keep frame for reassembly later */
5151 l2cap_pass_to_tx(chan, control);
5152 skb_queue_tail(&chan->srej_q, skb);
5153 skb_in_use = 1;
5154 BT_DBG("Queued %p (queue len %d)", skb,
5155 skb_queue_len(&chan->srej_q));
5156
5157 chan->expected_tx_seq = __next_seq(chan, txseq);
5158 break;
5159 case L2CAP_TXSEQ_EXPECTED_SREJ:
5160 l2cap_seq_list_pop(&chan->srej_list);
5161
5162 l2cap_pass_to_tx(chan, control);
5163 skb_queue_tail(&chan->srej_q, skb);
5164 skb_in_use = 1;
5165 BT_DBG("Queued %p (queue len %d)", skb,
5166 skb_queue_len(&chan->srej_q));
5167
5168 err = l2cap_rx_queued_iframes(chan);
5169 if (err)
5170 break;
5171
5172 break;
5173 case L2CAP_TXSEQ_UNEXPECTED:
5174 /* Got a frame that can't be reassembled yet.
5175 * Save it for later, and send SREJs to cover
5176 * the missing frames.
5177 */
5178 skb_queue_tail(&chan->srej_q, skb);
5179 skb_in_use = 1;
5180 BT_DBG("Queued %p (queue len %d)", skb,
5181 skb_queue_len(&chan->srej_q));
5182
5183 l2cap_pass_to_tx(chan, control);
5184 l2cap_send_srej(chan, control->txseq);
5185 break;
5186 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
5187 /* This frame was requested with an SREJ, but
5188 * some expected retransmitted frames are
5189 * missing. Request retransmission of missing
5190 * SREJ'd frames.
5191 */
5192 skb_queue_tail(&chan->srej_q, skb);
5193 skb_in_use = 1;
5194 BT_DBG("Queued %p (queue len %d)", skb,
5195 skb_queue_len(&chan->srej_q));
5196
5197 l2cap_pass_to_tx(chan, control);
5198 l2cap_send_srej_list(chan, control->txseq);
5199 break;
5200 case L2CAP_TXSEQ_DUPLICATE_SREJ:
5201 /* We've already queued this frame. Drop this copy. */
5202 l2cap_pass_to_tx(chan, control);
5203 break;
5204 case L2CAP_TXSEQ_DUPLICATE:
5205 /* Expecting a later sequence number, so this frame
5206 * was already received. Ignore it completely.
5207 */
5208 break;
5209 case L2CAP_TXSEQ_INVALID_IGNORE:
5210 break;
5211 case L2CAP_TXSEQ_INVALID:
5212 default:
5213 l2cap_send_disconn_req(chan->conn, chan,
5214 ECONNRESET);
5215 break;
5216 }
5217 break;
5218 case L2CAP_EV_RECV_RR:
5219 l2cap_pass_to_tx(chan, control);
5220 if (control->final) {
5221 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5222
5223 if (!test_and_clear_bit(CONN_REJ_ACT,
5224 &chan->conn_state)) {
5225 control->final = 0;
5226 l2cap_retransmit_all(chan, control);
5227 }
5228
5229 l2cap_ertm_send(chan);
5230 } else if (control->poll) {
5231 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5232 &chan->conn_state) &&
5233 chan->unacked_frames) {
5234 __set_retrans_timer(chan);
5235 }
5236
5237 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5238 l2cap_send_srej_tail(chan);
5239 } else {
5240 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5241 &chan->conn_state) &&
5242 chan->unacked_frames)
5243 __set_retrans_timer(chan);
5244
5245 l2cap_send_ack(chan);
5246 }
5247 break;
5248 case L2CAP_EV_RECV_RNR:
5249 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5250 l2cap_pass_to_tx(chan, control);
5251 if (control->poll) {
5252 l2cap_send_srej_tail(chan);
5253 } else {
5254 struct l2cap_ctrl rr_control;
5255 memset(&rr_control, 0, sizeof(rr_control));
5256 rr_control.sframe = 1;
5257 rr_control.super = L2CAP_SUPER_RR;
5258 rr_control.reqseq = chan->buffer_seq;
5259 l2cap_send_sframe(chan, &rr_control);
5260 }
5261
5262 break;
5263 case L2CAP_EV_RECV_REJ:
5264 l2cap_handle_rej(chan, control);
5265 break;
5266 case L2CAP_EV_RECV_SREJ:
5267 l2cap_handle_srej(chan, control);
5268 break;
5269 }
5270
5271 if (skb && !skb_in_use) {
5272 BT_DBG("Freeing %p", skb);
5273 kfree_skb(skb);
5274 }
5275
5276 return err;
5277}
5278
Mat Martineau32b32732012-10-23 15:24:11 -07005279static int l2cap_finish_move(struct l2cap_chan *chan)
5280{
5281 BT_DBG("chan %p", chan);
5282
5283 chan->rx_state = L2CAP_RX_STATE_RECV;
5284
5285 if (chan->hs_hcon)
5286 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
5287 else
5288 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
5289
5290 return l2cap_resegment(chan);
5291}
5292
5293static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
5294 struct l2cap_ctrl *control,
5295 struct sk_buff *skb, u8 event)
5296{
5297 int err;
5298
5299 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5300 event);
5301
5302 if (!control->poll)
5303 return -EPROTO;
5304
5305 l2cap_process_reqseq(chan, control->reqseq);
5306
5307 if (!skb_queue_empty(&chan->tx_q))
5308 chan->tx_send_head = skb_peek(&chan->tx_q);
5309 else
5310 chan->tx_send_head = NULL;
5311
5312 /* Rewind next_tx_seq to the point expected
5313 * by the receiver.
5314 */
5315 chan->next_tx_seq = control->reqseq;
5316 chan->unacked_frames = 0;
5317
5318 err = l2cap_finish_move(chan);
5319 if (err)
5320 return err;
5321
5322 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5323 l2cap_send_i_or_rr_or_rnr(chan);
5324
5325 if (event == L2CAP_EV_RECV_IFRAME)
5326 return -EPROTO;
5327
5328 return l2cap_rx_state_recv(chan, control, NULL, event);
5329}
5330
5331static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
5332 struct l2cap_ctrl *control,
5333 struct sk_buff *skb, u8 event)
5334{
5335 int err;
5336
5337 if (!control->final)
5338 return -EPROTO;
5339
5340 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5341
5342 chan->rx_state = L2CAP_RX_STATE_RECV;
5343 l2cap_process_reqseq(chan, control->reqseq);
5344
5345 if (!skb_queue_empty(&chan->tx_q))
5346 chan->tx_send_head = skb_peek(&chan->tx_q);
5347 else
5348 chan->tx_send_head = NULL;
5349
5350 /* Rewind next_tx_seq to the point expected
5351 * by the receiver.
5352 */
5353 chan->next_tx_seq = control->reqseq;
5354 chan->unacked_frames = 0;
5355
5356 if (chan->hs_hcon)
5357 chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
5358 else
5359 chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
5360
5361 err = l2cap_resegment(chan);
5362
5363 if (!err)
5364 err = l2cap_rx_state_recv(chan, control, skb, event);
5365
5366 return err;
5367}
5368
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005369static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
5370{
5371 /* Make sure reqseq is for a packet that has been sent but not acked */
5372 u16 unacked;
5373
5374 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
5375 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
5376}
5377
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005378static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5379 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005380{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005381 int err = 0;
5382
5383 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
5384 control, skb, event, chan->rx_state);
5385
5386 if (__valid_reqseq(chan, control->reqseq)) {
5387 switch (chan->rx_state) {
5388 case L2CAP_RX_STATE_RECV:
5389 err = l2cap_rx_state_recv(chan, control, skb, event);
5390 break;
5391 case L2CAP_RX_STATE_SREJ_SENT:
5392 err = l2cap_rx_state_srej_sent(chan, control, skb,
5393 event);
5394 break;
Mat Martineau32b32732012-10-23 15:24:11 -07005395 case L2CAP_RX_STATE_WAIT_P:
5396 err = l2cap_rx_state_wait_p(chan, control, skb, event);
5397 break;
5398 case L2CAP_RX_STATE_WAIT_F:
5399 err = l2cap_rx_state_wait_f(chan, control, skb, event);
5400 break;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005401 default:
5402 /* shut it down */
5403 break;
5404 }
5405 } else {
5406 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
5407 control->reqseq, chan->next_tx_seq,
5408 chan->expected_ack_seq);
5409 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
5410 }
5411
5412 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005413}
5414
5415static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5416 struct sk_buff *skb)
5417{
Mat Martineau4b51dae92012-05-17 20:53:37 -07005418 int err = 0;
5419
5420 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
5421 chan->rx_state);
5422
5423 if (l2cap_classify_txseq(chan, control->txseq) ==
5424 L2CAP_TXSEQ_EXPECTED) {
5425 l2cap_pass_to_tx(chan, control);
5426
5427 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
5428 __next_seq(chan, chan->buffer_seq));
5429
5430 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5431
5432 l2cap_reassemble_sdu(chan, skb, control);
5433 } else {
5434 if (chan->sdu) {
5435 kfree_skb(chan->sdu);
5436 chan->sdu = NULL;
5437 }
5438 chan->sdu_last_frag = NULL;
5439 chan->sdu_len = 0;
5440
5441 if (skb) {
5442 BT_DBG("Freeing %p", skb);
5443 kfree_skb(skb);
5444 }
5445 }
5446
5447 chan->last_acked_seq = control->txseq;
5448 chan->expected_tx_seq = __next_seq(chan, control->txseq);
5449
5450 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005451}
5452
5453static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
5454{
5455 struct l2cap_ctrl *control = &bt_cb(skb)->control;
5456 u16 len;
5457 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005458
Mat Martineaub76bbd62012-04-11 10:48:43 -07005459 __unpack_control(chan, skb);
5460
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005461 len = skb->len;
5462
5463 /*
5464 * We can just drop the corrupted I-frame here.
5465 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005466 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005467 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005468 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005469 goto drop;
5470
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005471 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005472 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005473
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005474 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005475 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005476
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005477 if (len > chan->mps) {
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005478 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005479 goto drop;
5480 }
5481
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005482 if (!control->sframe) {
5483 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005484
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005485 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
5486 control->sar, control->reqseq, control->final,
5487 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03005488
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005489 /* Validate F-bit - F=0 always valid, F=1 only
5490 * valid in TX WAIT_F
5491 */
5492 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005493 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005494
5495 if (chan->mode != L2CAP_MODE_STREAMING) {
5496 event = L2CAP_EV_RECV_IFRAME;
5497 err = l2cap_rx(chan, control, skb, event);
5498 } else {
5499 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005500 }
5501
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005502 if (err)
5503 l2cap_send_disconn_req(chan->conn, chan,
5504 ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005505 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005506 const u8 rx_func_to_event[4] = {
5507 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
5508 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
5509 };
5510
5511 /* Only I-frames are expected in streaming mode */
5512 if (chan->mode == L2CAP_MODE_STREAMING)
5513 goto drop;
5514
5515 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
5516 control->reqseq, control->final, control->poll,
5517 control->super);
5518
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005519 if (len != 0) {
5520 BT_ERR("%d", len);
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005521 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005522 goto drop;
5523 }
5524
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005525 /* Validate F and P bits */
5526 if (control->final && (control->poll ||
5527 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
5528 goto drop;
5529
5530 event = rx_func_to_event[control->super];
5531 if (l2cap_rx(chan, control, skb, event))
5532 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005533 }
5534
5535 return 0;
5536
5537drop:
5538 kfree_skb(skb);
5539 return 0;
5540}
5541
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005542static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
5543 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005544{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005545 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005546
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03005547 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005548 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005549 if (cid == L2CAP_CID_A2MP) {
5550 chan = a2mp_channel_create(conn, skb);
5551 if (!chan) {
5552 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005553 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005554 }
5555
5556 l2cap_chan_lock(chan);
5557 } else {
5558 BT_DBG("unknown cid 0x%4.4x", cid);
5559 /* Drop packet and return */
5560 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005561 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005562 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005563 }
5564
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03005565 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005566
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005567 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005568 goto drop;
5569
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005570 switch (chan->mode) {
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03005571 case L2CAP_MODE_BASIC:
5572 /* If socket recv buffers overflows we drop data here
5573 * which is *bad* because L2CAP has to be reliable.
5574 * But we don't have any other choice. L2CAP doesn't
5575 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005576
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005577 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03005578 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005579
Gustavo Padovan80b98022012-05-27 22:27:51 -03005580 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03005581 goto done;
5582 break;
5583
5584 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005585 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005586 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005587 goto done;
5588
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03005589 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005590 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03005591 break;
5592 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005593
5594drop:
5595 kfree_skb(skb);
5596
5597done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005598 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005599}
5600
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03005601static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
5602 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005603{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005604 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005605
Ido Yarivc2287682012-04-20 15:46:07 -03005606 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005607 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005608 goto drop;
5609
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005610 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005611
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005612 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005613 goto drop;
5614
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005615 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005616 goto drop;
5617
Gustavo Padovan80b98022012-05-27 22:27:51 -03005618 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03005619 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005620
5621drop:
5622 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005623}
5624
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03005625static void l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
5626 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005627{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005628 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005629
Ido Yarivc2287682012-04-20 15:46:07 -03005630 chan = l2cap_global_chan_by_scid(0, cid, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005631 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005632 goto drop;
5633
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005634 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005635
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005636 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005637 goto drop;
5638
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005639 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005640 goto drop;
5641
Gustavo Padovan80b98022012-05-27 22:27:51 -03005642 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03005643 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005644
5645drop:
5646 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005647}
5648
Linus Torvalds1da177e2005-04-16 15:20:36 -07005649static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
5650{
5651 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07005652 u16 cid, len;
5653 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005654
5655 skb_pull(skb, L2CAP_HDR_SIZE);
5656 cid = __le16_to_cpu(lh->cid);
5657 len = __le16_to_cpu(lh->len);
5658
Gustavo F. Padovan1c2acffb72009-08-20 22:25:57 -03005659 if (len != skb->len) {
5660 kfree_skb(skb);
5661 return;
5662 }
5663
Linus Torvalds1da177e2005-04-16 15:20:36 -07005664 BT_DBG("len %d, cid 0x%4.4x", len, cid);
5665
5666 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005667 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005668 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005669 l2cap_sig_channel(conn, skb);
5670 break;
5671
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005672 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02005673 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03005674 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005675 l2cap_conless_channel(conn, psm, skb);
5676 break;
5677
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005678 case L2CAP_CID_LE_DATA:
5679 l2cap_att_channel(conn, cid, skb);
5680 break;
5681
Anderson Brigliab501d6a2011-06-07 18:46:31 -03005682 case L2CAP_CID_SMP:
5683 if (smp_sig_channel(conn, skb))
5684 l2cap_conn_del(conn->hcon, EACCES);
5685 break;
5686
Linus Torvalds1da177e2005-04-16 15:20:36 -07005687 default:
5688 l2cap_data_channel(conn, cid, skb);
5689 break;
5690 }
5691}
5692
5693/* ---- L2CAP interface with lower layer (HCI) ---- */
5694
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005695int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005696{
5697 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005698 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005699
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03005700 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005701
5702 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005703 read_lock(&chan_list_lock);
5704 list_for_each_entry(c, &chan_list, global_l) {
5705 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005706
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005707 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005708 continue;
5709
5710 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005711 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005712 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005713 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005714 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005715 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
5716 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005717 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005718 lm2 |= HCI_LM_MASTER;
5719 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005720 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005721 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005722
5723 return exact ? lm1 : lm2;
5724}
5725
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03005726void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005727{
Marcel Holtmann01394182006-07-03 10:02:46 +02005728 struct l2cap_conn *conn;
5729
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03005730 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005731
Linus Torvalds1da177e2005-04-16 15:20:36 -07005732 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005733 conn = l2cap_conn_add(hcon, status);
5734 if (conn)
5735 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02005736 } else
Joe Perchese1750722011-06-29 18:18:29 -07005737 l2cap_conn_del(hcon, bt_to_errno(status));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005738
Linus Torvalds1da177e2005-04-16 15:20:36 -07005739}
5740
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005741int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01005742{
5743 struct l2cap_conn *conn = hcon->l2cap_data;
5744
5745 BT_DBG("hcon %p", hcon);
5746
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005747 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02005748 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01005749 return conn->disc_reason;
5750}
5751
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03005752void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005753{
5754 BT_DBG("hcon %p reason %d", hcon, reason);
5755
Joe Perchese1750722011-06-29 18:18:29 -07005756 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005757}
5758
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005759static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005760{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03005761 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01005762 return;
5763
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005764 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005765 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005766 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005767 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03005768 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005769 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005770 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03005771 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005772 }
5773}
5774
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005775int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005776{
Marcel Holtmann40be4922008-07-14 20:13:50 +02005777 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005778 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005779
Marcel Holtmann01394182006-07-03 10:02:46 +02005780 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005781 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02005782
Andrei Emeltchenko89d8b4072012-07-10 15:27:51 +03005783 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005784
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005785 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05305786 if (!status && encrypt)
5787 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02005788 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005789 }
5790
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005791 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005792
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005793 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005794 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005795
Andrei Emeltchenko89d8b4072012-07-10 15:27:51 +03005796 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
5797 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005798
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03005799 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
5800 l2cap_chan_unlock(chan);
5801 continue;
5802 }
5803
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005804 if (chan->scid == L2CAP_CID_LE_DATA) {
5805 if (!status && encrypt) {
5806 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02005807 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005808 }
5809
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005810 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005811 continue;
5812 }
5813
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03005814 if (test_bit(CONF_CONNECT_PEND, &chan->conf_state)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005815 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01005816 continue;
5817 }
5818
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005819 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01005820 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03005821 struct sock *sk = chan->sk;
5822
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005823 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03005824 sk->sk_state_change(sk);
5825
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005826 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005827 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02005828 continue;
5829 }
5830
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005831 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02005832 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03005833 l2cap_start_connection(chan);
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02005834 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005835 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02005836 }
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005837 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005838 struct sock *sk = chan->sk;
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02005839 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005840 __u16 res, stat;
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02005841
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005842 lock_sock(sk);
5843
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02005844 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005845 if (test_bit(BT_SK_DEFER_SETUP,
5846 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005847 res = L2CAP_CR_PEND;
5848 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08005849 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005850 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005851 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005852 res = L2CAP_CR_SUCCESS;
5853 stat = L2CAP_CS_NO_INFO;
5854 }
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02005855 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005856 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005857 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005858 res = L2CAP_CR_SEC_BLOCK;
5859 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02005860 }
5861
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005862 release_sock(sk);
5863
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03005864 rsp.scid = cpu_to_le16(chan->dcid);
5865 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005866 rsp.result = cpu_to_le16(res);
5867 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03005868 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005869 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07005870
5871 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
5872 res == L2CAP_CR_SUCCESS) {
5873 char buf[128];
5874 set_bit(CONF_REQ_SENT, &chan->conf_state);
5875 l2cap_send_cmd(conn, l2cap_get_ident(conn),
5876 L2CAP_CONF_REQ,
5877 l2cap_build_conf_req(chan, buf),
5878 buf);
5879 chan->num_conf_req++;
5880 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005881 }
5882
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005883 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005884 }
5885
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005886 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d7962008-07-14 20:13:54 +02005887
Linus Torvalds1da177e2005-04-16 15:20:36 -07005888 return 0;
5889}
5890
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005891int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005892{
5893 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03005894 struct l2cap_hdr *hdr;
5895 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005896
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03005897 /* For AMP controller do not create l2cap conn */
5898 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
5899 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005900
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02005901 if (!conn)
5902 conn = l2cap_conn_add(hcon, 0);
5903
5904 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005905 goto drop;
5906
5907 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
5908
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03005909 switch (flags) {
5910 case ACL_START:
5911 case ACL_START_NO_FLUSH:
5912 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005913 if (conn->rx_len) {
5914 BT_ERR("Unexpected start frame (len %d)", skb->len);
5915 kfree_skb(conn->rx_skb);
5916 conn->rx_skb = NULL;
5917 conn->rx_len = 0;
5918 l2cap_conn_unreliable(conn, ECOMM);
5919 }
5920
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03005921 /* Start fragment always begin with Basic L2CAP header */
5922 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005923 BT_ERR("Frame is too short (len %d)", skb->len);
5924 l2cap_conn_unreliable(conn, ECOMM);
5925 goto drop;
5926 }
5927
5928 hdr = (struct l2cap_hdr *) skb->data;
5929 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
5930
5931 if (len == skb->len) {
5932 /* Complete frame received */
5933 l2cap_recv_frame(conn, skb);
5934 return 0;
5935 }
5936
5937 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
5938
5939 if (skb->len > len) {
5940 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01005941 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005942 l2cap_conn_unreliable(conn, ECOMM);
5943 goto drop;
5944 }
5945
5946 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03005947 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03005948 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005949 goto drop;
5950
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005951 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01005952 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005953 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03005954 break;
5955
5956 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005957 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
5958
5959 if (!conn->rx_len) {
5960 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
5961 l2cap_conn_unreliable(conn, ECOMM);
5962 goto drop;
5963 }
5964
5965 if (skb->len > conn->rx_len) {
5966 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01005967 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005968 kfree_skb(conn->rx_skb);
5969 conn->rx_skb = NULL;
5970 conn->rx_len = 0;
5971 l2cap_conn_unreliable(conn, ECOMM);
5972 goto drop;
5973 }
5974
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005975 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01005976 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005977 conn->rx_len -= skb->len;
5978
5979 if (!conn->rx_len) {
5980 /* Complete frame received */
5981 l2cap_recv_frame(conn, conn->rx_skb);
5982 conn->rx_skb = NULL;
5983 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03005984 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005985 }
5986
5987drop:
5988 kfree_skb(skb);
5989 return 0;
5990}
5991
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005992static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005993{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005994 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005995
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005996 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005997
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005998 list_for_each_entry(c, &chan_list, global_l) {
5999 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006000
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03006001 seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
6002 &bt_sk(sk)->src, &bt_sk(sk)->dst,
6003 c->state, __le16_to_cpu(c->psm),
6004 c->scid, c->dcid, c->imtu, c->omtu,
6005 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02006006 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006007
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02006008 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006009
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006010 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006011}
6012
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006013static int l2cap_debugfs_open(struct inode *inode, struct file *file)
6014{
6015 return single_open(file, l2cap_debugfs_show, inode->i_private);
6016}
6017
6018static const struct file_operations l2cap_debugfs_fops = {
6019 .open = l2cap_debugfs_open,
6020 .read = seq_read,
6021 .llseek = seq_lseek,
6022 .release = single_release,
6023};
6024
6025static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006026
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006027int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006028{
6029 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08006030
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006031 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006032 if (err < 0)
6033 return err;
6034
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006035 if (bt_debugfs) {
Gustavo Padovan2d792812012-10-06 10:07:01 +01006036 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
6037 NULL, &l2cap_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006038 if (!l2cap_debugfs)
6039 BT_ERR("Failed to create L2CAP debug file");
6040 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006041
Linus Torvalds1da177e2005-04-16 15:20:36 -07006042 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006043}
6044
Gustavo F. Padovan64274512011-02-07 20:08:52 -02006045void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006046{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01006047 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02006048 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006049}
6050
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03006051module_param(disable_ertm, bool, 0644);
6052MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");