blob: 781a085ae5bc4da76d6c26b29c0547b570ee87cb [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,
51 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,
53 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,
Mat Martineau608bcc62012-05-17 20:53:32 -070059 struct sk_buff_head *skbs, u8 event);
60
Marcel Holtmann01394182006-07-03 10:02:46 +020061/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030062
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030063static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020064{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020065 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030066
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020067 list_for_each_entry(c, &conn->chan_l, list) {
68 if (c->dcid == cid)
69 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020070 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020071 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020072}
73
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030074static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020075{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020076 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030077
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020078 list_for_each_entry(c, &conn->chan_l, list) {
79 if (c->scid == cid)
80 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020081 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020082 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020083}
84
85/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -070086 * Returns locked channel. */
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030087static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020088{
Gustavo F. Padovan48454072011-03-25 00:22:30 -030089 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030090
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020091 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030092 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -070093 if (c)
94 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020095 mutex_unlock(&conn->chan_lock);
96
Gustavo F. Padovan48454072011-03-25 00:22:30 -030097 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020098}
99
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300100static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200101{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200102 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300103
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200104 list_for_each_entry(c, &conn->chan_l, list) {
105 if (c->ident == ident)
106 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200107 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200108 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200109}
110
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300111static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300112{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300113 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300114
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300115 list_for_each_entry(c, &chan_list, global_l) {
116 if (c->sport == psm && !bacmp(&bt_sk(c->sk)->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100117 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300118 }
Szymon Janc250938c2011-11-16 09:32:22 +0100119 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300120}
121
122int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
123{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300124 int err;
125
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200126 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300127
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300128 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300129 err = -EADDRINUSE;
130 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300131 }
132
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300133 if (psm) {
134 chan->psm = psm;
135 chan->sport = psm;
136 err = 0;
137 } else {
138 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300139
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300140 err = -EINVAL;
141 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300142 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300143 chan->psm = cpu_to_le16(p);
144 chan->sport = cpu_to_le16(p);
145 err = 0;
146 break;
147 }
148 }
149
150done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200151 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300152 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300153}
154
155int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
156{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200157 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300158
159 chan->scid = scid;
160
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200161 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300162
163 return 0;
164}
165
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300166static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200167{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300168 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200169
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300170 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300171 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200172 return cid;
173 }
174
175 return 0;
176}
177
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200178static void __l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300179{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200180 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200181 state_to_string(state));
182
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300183 chan->state = state;
Gustavo Padovan80b98022012-05-27 22:27:51 -0300184 chan->ops->state_change(chan, state);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300185}
186
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200187static void l2cap_state_change(struct l2cap_chan *chan, int state)
188{
189 struct sock *sk = chan->sk;
190
191 lock_sock(sk);
192 __l2cap_state_change(chan, state);
193 release_sock(sk);
194}
195
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200196static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err)
197{
198 struct sock *sk = chan->sk;
199
200 sk->sk_err = err;
201}
202
203static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
204{
205 struct sock *sk = chan->sk;
206
207 lock_sock(sk);
208 __l2cap_chan_set_err(chan, err);
209 release_sock(sk);
210}
211
Mat Martineau4239d162012-05-17 20:53:49 -0700212static void __set_retrans_timer(struct l2cap_chan *chan)
213{
214 if (!delayed_work_pending(&chan->monitor_timer) &&
215 chan->retrans_timeout) {
216 l2cap_set_timer(chan, &chan->retrans_timer,
217 msecs_to_jiffies(chan->retrans_timeout));
218 }
219}
220
221static void __set_monitor_timer(struct l2cap_chan *chan)
222{
223 __clear_retrans_timer(chan);
224 if (chan->monitor_timeout) {
225 l2cap_set_timer(chan, &chan->monitor_timer,
226 msecs_to_jiffies(chan->monitor_timeout));
227 }
228}
229
Mat Martineau608bcc62012-05-17 20:53:32 -0700230static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
231 u16 seq)
232{
233 struct sk_buff *skb;
234
235 skb_queue_walk(head, skb) {
236 if (bt_cb(skb)->control.txseq == seq)
237 return skb;
238 }
239
240 return NULL;
241}
242
Mat Martineau3c588192012-04-11 10:48:42 -0700243/* ---- L2CAP sequence number lists ---- */
244
245/* For ERTM, ordered lists of sequence numbers must be tracked for
246 * SREJ requests that are received and for frames that are to be
247 * retransmitted. These seq_list functions implement a singly-linked
248 * list in an array, where membership in the list can also be checked
249 * in constant time. Items can also be added to the tail of the list
250 * and removed from the head in constant time, without further memory
251 * allocs or frees.
252 */
253
254static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
255{
256 size_t alloc_size, i;
257
258 /* Allocated size is a power of 2 to map sequence numbers
259 * (which may be up to 14 bits) in to a smaller array that is
260 * sized for the negotiated ERTM transmit windows.
261 */
262 alloc_size = roundup_pow_of_two(size);
263
264 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
265 if (!seq_list->list)
266 return -ENOMEM;
267
268 seq_list->mask = alloc_size - 1;
269 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
270 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
271 for (i = 0; i < alloc_size; i++)
272 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
273
274 return 0;
275}
276
277static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
278{
279 kfree(seq_list->list);
280}
281
282static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
283 u16 seq)
284{
285 /* Constant-time check for list membership */
286 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
287}
288
289static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
290{
291 u16 mask = seq_list->mask;
292
293 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
294 /* In case someone tries to pop the head of an empty list */
295 return L2CAP_SEQ_LIST_CLEAR;
296 } else if (seq_list->head == seq) {
297 /* Head can be removed in constant time */
298 seq_list->head = seq_list->list[seq & mask];
299 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
300
301 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
302 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
303 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
304 }
305 } else {
306 /* Walk the list to find the sequence number */
307 u16 prev = seq_list->head;
308 while (seq_list->list[prev & mask] != seq) {
309 prev = seq_list->list[prev & mask];
310 if (prev == L2CAP_SEQ_LIST_TAIL)
311 return L2CAP_SEQ_LIST_CLEAR;
312 }
313
314 /* Unlink the number from the list and clear it */
315 seq_list->list[prev & mask] = seq_list->list[seq & mask];
316 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
317 if (seq_list->tail == seq)
318 seq_list->tail = prev;
319 }
320 return seq;
321}
322
323static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
324{
325 /* Remove the head in constant time */
326 return l2cap_seq_list_remove(seq_list, seq_list->head);
327}
328
329static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
330{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300331 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700332
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300333 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
334 return;
335
336 for (i = 0; i <= seq_list->mask; i++)
337 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
338
339 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
340 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700341}
342
343static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
344{
345 u16 mask = seq_list->mask;
346
347 /* All appends happen in constant time */
348
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300349 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
350 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700351
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300352 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
353 seq_list->head = seq;
354 else
355 seq_list->list[seq_list->tail & mask] = seq;
356
357 seq_list->tail = seq;
358 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700359}
360
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300361static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300362{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300363 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
364 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200365 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300366 int reason;
367
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200368 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300369
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200370 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200371 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300372
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300373 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300374 reason = ECONNREFUSED;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300375 else if (chan->state == BT_CONNECT &&
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300376 chan->sec_level != BT_SECURITY_SDP)
377 reason = ECONNREFUSED;
378 else
379 reason = ETIMEDOUT;
380
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300381 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300382
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200383 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300384
Gustavo Padovan80b98022012-05-27 22:27:51 -0300385 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200386 mutex_unlock(&conn->chan_lock);
387
Ulisses Furquim371fd832011-12-21 20:02:36 -0200388 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300389}
390
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300391struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200392{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300393 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200394
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300395 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
396 if (!chan)
397 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200398
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200399 mutex_init(&chan->lock);
400
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200401 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300402 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200403 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300404
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300405 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300406
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300407 chan->state = BT_OPEN;
408
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530409 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300410
Mat Martineau28270112012-05-17 21:14:09 -0700411 /* This flag is cleared in l2cap_chan_ready() */
412 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
413
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300414 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100415
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300416 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200417}
418
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530419static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300420{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530421 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
422
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530423 BT_DBG("chan %p", chan);
424
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200425 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300426 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200427 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300428
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530429 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300430}
431
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530432void l2cap_chan_hold(struct l2cap_chan *c)
433{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530434 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530435
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530436 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530437}
438
439void l2cap_chan_put(struct l2cap_chan *c)
440{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530441 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530442
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530443 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530444}
445
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300446void l2cap_chan_set_defaults(struct l2cap_chan *chan)
447{
448 chan->fcs = L2CAP_FCS_CRC16;
449 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
450 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
451 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700452 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300453 chan->sec_level = BT_SECURITY_LOW;
454
455 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
456}
457
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300458void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200459{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300460 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200461 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200462
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200463 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100464
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300465 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200466
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200467 switch (chan->chan_type) {
468 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300469 if (conn->hcon->type == LE_LINK) {
470 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300471 chan->omtu = L2CAP_DEFAULT_MTU;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300472 chan->scid = L2CAP_CID_LE_DATA;
473 chan->dcid = L2CAP_CID_LE_DATA;
Ville Tervob62f3282011-02-10 22:38:50 -0300474 } else {
475 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300476 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300477 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300478 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200479 break;
480
481 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200482 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300483 chan->scid = L2CAP_CID_CONN_LESS;
484 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300485 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200486 break;
487
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300488 case L2CAP_CHAN_CONN_FIX_A2MP:
489 chan->scid = L2CAP_CID_A2MP;
490 chan->dcid = L2CAP_CID_A2MP;
491 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
492 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
493 break;
494
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200495 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200496 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300497 chan->scid = L2CAP_CID_SIGNALING;
498 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300499 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200500 }
501
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300502 chan->local_id = L2CAP_BESTEFFORT_ID;
503 chan->local_stype = L2CAP_SERV_BESTEFFORT;
504 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
505 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
506 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
507 chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO;
508
Ulisses Furquim371fd832011-12-21 20:02:36 -0200509 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300510
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200511 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200512}
513
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300514void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200515{
516 mutex_lock(&conn->chan_lock);
517 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200518 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200519}
520
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300521void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200522{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300523 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200524
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300525 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200526
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300527 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200528
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900529 if (conn) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300530 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200531 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200532
Ulisses Furquim371fd832011-12-21 20:02:36 -0200533 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300534
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300535 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300536
537 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
538 hci_conn_put(conn->hcon);
Marcel Holtmann01394182006-07-03 10:02:46 +0200539 }
540
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300541 if (chan->ops->teardown)
542 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200543
Mat Martineau28270112012-05-17 21:14:09 -0700544 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300545 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300546
Gustavo Padovanee556f62012-05-18 20:22:38 -0300547 switch(chan->mode) {
548 case L2CAP_MODE_BASIC:
549 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300550
Gustavo Padovanee556f62012-05-18 20:22:38 -0300551 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300552 __clear_retrans_timer(chan);
553 __clear_monitor_timer(chan);
554 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300555
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300556 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300557
Mat Martineau3c588192012-04-11 10:48:42 -0700558 l2cap_seq_list_free(&chan->srej_list);
559 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300560
561 /* fall through */
562
563 case L2CAP_MODE_STREAMING:
564 skb_queue_purge(&chan->tx_q);
565 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300566 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300567
568 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200569}
570
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300571void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300572{
573 struct l2cap_conn *conn = chan->conn;
574 struct sock *sk = chan->sk;
575
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200576 BT_DBG("chan %p state %s sk %p", chan,
577 state_to_string(chan->state), sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300578
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300579 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300580 case BT_LISTEN:
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300581 if (chan->ops->teardown)
582 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300583 break;
584
585 case BT_CONNECTED:
586 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300587 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300588 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300589 __set_chan_timer(chan, sk->sk_sndtimeo);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300590 l2cap_send_disconn_req(conn, chan, reason);
591 } else
592 l2cap_chan_del(chan, reason);
593 break;
594
595 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300596 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300597 conn->hcon->type == ACL_LINK) {
598 struct l2cap_conn_rsp rsp;
599 __u16 result;
600
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300601 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300602 result = L2CAP_CR_SEC_BLOCK;
603 else
604 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300605 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300606
607 rsp.scid = cpu_to_le16(chan->dcid);
608 rsp.dcid = cpu_to_le16(chan->scid);
609 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300610 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300611 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
612 sizeof(rsp), &rsp);
613 }
614
615 l2cap_chan_del(chan, reason);
616 break;
617
618 case BT_CONNECT:
619 case BT_DISCONN:
620 l2cap_chan_del(chan, reason);
621 break;
622
623 default:
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300624 if (chan->ops->teardown)
625 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300626 break;
627 }
628}
629
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300630static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530631{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300632 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300633 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530634 case BT_SECURITY_HIGH:
635 return HCI_AT_DEDICATED_BONDING_MITM;
636 case BT_SECURITY_MEDIUM:
637 return HCI_AT_DEDICATED_BONDING;
638 default:
639 return HCI_AT_NO_BONDING;
640 }
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +0300641 } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300642 if (chan->sec_level == BT_SECURITY_LOW)
643 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530644
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300645 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530646 return HCI_AT_NO_BONDING_MITM;
647 else
648 return HCI_AT_NO_BONDING;
649 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300650 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530651 case BT_SECURITY_HIGH:
652 return HCI_AT_GENERAL_BONDING_MITM;
653 case BT_SECURITY_MEDIUM:
654 return HCI_AT_GENERAL_BONDING;
655 default:
656 return HCI_AT_NO_BONDING;
657 }
658 }
659}
660
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200661/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200662int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200663{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300664 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100665 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200666
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300667 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100668
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300669 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200670}
671
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200672static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200673{
674 u8 id;
675
676 /* Get next available identificator.
677 * 1 - 128 are used by kernel.
678 * 129 - 199 are reserved.
679 * 200 - 254 are used by utilities like l2ping, etc.
680 */
681
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200682 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200683
684 if (++conn->tx_ident > 128)
685 conn->tx_ident = 1;
686
687 id = conn->tx_ident;
688
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200689 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200690
691 return id;
692}
693
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300694static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200695{
696 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200697 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200698
699 BT_DBG("code 0x%2.2x", code);
700
701 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300702 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200703
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200704 if (lmp_no_flush_capable(conn->hcon->hdev))
705 flags = ACL_START_NO_FLUSH;
706 else
707 flags = ACL_START;
708
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700709 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200710 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700711
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200712 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200713}
714
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200715static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
716{
717 struct hci_conn *hcon = chan->conn->hcon;
718 u16 flags;
719
720 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
721 skb->priority);
722
723 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
724 lmp_no_flush_capable(hcon->hdev))
725 flags = ACL_START_NO_FLUSH;
726 else
727 flags = ACL_START;
728
729 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
730 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731}
732
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700733static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
734{
735 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
736 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
737
738 if (enh & L2CAP_CTRL_FRAME_TYPE) {
739 /* S-Frame */
740 control->sframe = 1;
741 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
742 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
743
744 control->sar = 0;
745 control->txseq = 0;
746 } else {
747 /* I-Frame */
748 control->sframe = 0;
749 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
750 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
751
752 control->poll = 0;
753 control->super = 0;
754 }
755}
756
757static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
758{
759 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
760 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
761
762 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
763 /* S-Frame */
764 control->sframe = 1;
765 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
766 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
767
768 control->sar = 0;
769 control->txseq = 0;
770 } else {
771 /* I-Frame */
772 control->sframe = 0;
773 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
774 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
775
776 control->poll = 0;
777 control->super = 0;
778 }
779}
780
781static inline void __unpack_control(struct l2cap_chan *chan,
782 struct sk_buff *skb)
783{
784 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
785 __unpack_extended_control(get_unaligned_le32(skb->data),
786 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700787 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700788 } else {
789 __unpack_enhanced_control(get_unaligned_le16(skb->data),
790 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700791 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700792 }
793}
794
795static u32 __pack_extended_control(struct l2cap_ctrl *control)
796{
797 u32 packed;
798
799 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
800 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
801
802 if (control->sframe) {
803 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
804 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
805 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
806 } else {
807 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
808 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
809 }
810
811 return packed;
812}
813
814static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
815{
816 u16 packed;
817
818 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
819 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
820
821 if (control->sframe) {
822 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
823 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
824 packed |= L2CAP_CTRL_FRAME_TYPE;
825 } else {
826 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
827 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
828 }
829
830 return packed;
831}
832
833static inline void __pack_control(struct l2cap_chan *chan,
834 struct l2cap_ctrl *control,
835 struct sk_buff *skb)
836{
837 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
838 put_unaligned_le32(__pack_extended_control(control),
839 skb->data + L2CAP_HDR_SIZE);
840 } else {
841 put_unaligned_le16(__pack_enhanced_control(control),
842 skb->data + L2CAP_HDR_SIZE);
843 }
844}
845
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300846static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
847{
848 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
849 return L2CAP_EXT_HDR_SIZE;
850 else
851 return L2CAP_ENH_HDR_SIZE;
852}
853
Mat Martineaua67d7f62012-05-17 20:53:35 -0700854static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
855 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300856{
857 struct sk_buff *skb;
858 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300859 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300860
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300861 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300862 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300863
Mat Martineaua67d7f62012-05-17 20:53:35 -0700864 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300865
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300866 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700867 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300868
869 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300870 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300871 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300872
Mat Martineaua67d7f62012-05-17 20:53:35 -0700873 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
874 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
875 else
876 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300877
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300878 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700879 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300880 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300881 }
882
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200883 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700884 return skb;
885}
886
887static void l2cap_send_sframe(struct l2cap_chan *chan,
888 struct l2cap_ctrl *control)
889{
890 struct sk_buff *skb;
891 u32 control_field;
892
893 BT_DBG("chan %p, control %p", chan, control);
894
895 if (!control->sframe)
896 return;
897
898 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
899 !control->poll)
900 control->final = 1;
901
902 if (control->super == L2CAP_SUPER_RR)
903 clear_bit(CONN_RNR_SENT, &chan->conn_state);
904 else if (control->super == L2CAP_SUPER_RNR)
905 set_bit(CONN_RNR_SENT, &chan->conn_state);
906
907 if (control->super != L2CAP_SUPER_SREJ) {
908 chan->last_acked_seq = control->reqseq;
909 __clear_ack_timer(chan);
910 }
911
912 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
913 control->final, control->poll, control->super);
914
915 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
916 control_field = __pack_extended_control(control);
917 else
918 control_field = __pack_enhanced_control(control);
919
920 skb = l2cap_create_sframe_pdu(chan, control_field);
921 if (!IS_ERR(skb))
922 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300923}
924
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700925static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300926{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700927 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300928
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700929 BT_DBG("chan %p, poll %d", chan, poll);
930
931 memset(&control, 0, sizeof(control));
932 control.sframe = 1;
933 control.poll = poll;
934
935 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
936 control.super = L2CAP_SUPER_RNR;
937 else
938 control.super = L2CAP_SUPER_RR;
939
940 control.reqseq = chan->buffer_seq;
941 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300942}
943
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300944static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300945{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -0300946 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300947}
948
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300949static bool __amp_capable(struct l2cap_chan *chan)
950{
951 struct l2cap_conn *conn = chan->conn;
952
953 if (enable_hs &&
954 chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED &&
955 conn->fixed_chan_mask & L2CAP_FC_A2MP)
956 return true;
957 else
958 return false;
959}
960
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +0200961static void l2cap_send_conn_req(struct l2cap_chan *chan)
962{
963 struct l2cap_conn *conn = chan->conn;
964 struct l2cap_conn_req req;
965
966 req.scid = cpu_to_le16(chan->scid);
967 req.psm = chan->psm;
968
969 chan->ident = l2cap_get_ident(conn);
970
971 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
972
973 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
974}
975
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300976static void l2cap_chan_ready(struct l2cap_chan *chan)
977{
Mat Martineau28270112012-05-17 21:14:09 -0700978 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300979 chan->conf_state = 0;
980 __clear_chan_timer(chan);
981
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -0300982 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300983
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +0300984 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300985}
986
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300987static void l2cap_start_connection(struct l2cap_chan *chan)
988{
989 if (__amp_capable(chan)) {
990 BT_DBG("chan %p AMP capable: discover AMPs", chan);
991 a2mp_discover_amp(chan);
992 } else {
993 l2cap_send_conn_req(chan);
994 }
995}
996
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -0300997static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200998{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300999 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001000
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001001 if (conn->hcon->type == LE_LINK) {
1002 l2cap_chan_ready(chan);
1003 return;
1004 }
1005
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001006 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001007 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1008 return;
1009
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001010 if (l2cap_chan_check_security(chan) &&
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001011 __l2cap_no_conn_pending(chan)) {
1012 l2cap_start_connection(chan);
1013 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001014 } else {
1015 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001016 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001017
1018 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1019 conn->info_ident = l2cap_get_ident(conn);
1020
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001021 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001022
1023 l2cap_send_cmd(conn, conn->info_ident,
1024 L2CAP_INFO_REQ, sizeof(req), &req);
1025 }
1026}
1027
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001028static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1029{
1030 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001031 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001032 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1033
1034 switch (mode) {
1035 case L2CAP_MODE_ERTM:
1036 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1037 case L2CAP_MODE_STREAMING:
1038 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1039 default:
1040 return 0x00;
1041 }
1042}
1043
Gustavo F. Padovan4519de92011-04-28 17:55:53 -03001044static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001045{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001046 struct sock *sk = chan->sk;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001047 struct l2cap_disconn_req req;
1048
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001049 if (!conn)
1050 return;
1051
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001052 if (chan->mode == L2CAP_MODE_ERTM) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001053 __clear_retrans_timer(chan);
1054 __clear_monitor_timer(chan);
1055 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001056 }
1057
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001058 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1059 __l2cap_state_change(chan, BT_DISCONN);
1060 return;
1061 }
1062
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001063 req.dcid = cpu_to_le16(chan->dcid);
1064 req.scid = cpu_to_le16(chan->scid);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001065 l2cap_send_cmd(conn, l2cap_get_ident(conn),
1066 L2CAP_DISCONN_REQ, sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001067
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001068 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001069 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001070 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001071 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001072}
1073
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001075static void l2cap_conn_start(struct l2cap_conn *conn)
1076{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001077 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001078
1079 BT_DBG("conn %p", conn);
1080
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001081 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001082
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001083 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001084 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001085
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001086 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001087
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001088 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001089 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001090 continue;
1091 }
1092
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001093 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001094 if (!l2cap_chan_check_security(chan) ||
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001095 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001096 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001097 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001098 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001099
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001100 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
1101 && test_bit(CONF_STATE2_DEVICE,
1102 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001103 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001104 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001105 continue;
1106 }
1107
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001108 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001109
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001110 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001111 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001112 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001113 rsp.scid = cpu_to_le16(chan->dcid);
1114 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001115
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001116 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001117 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001118 if (test_bit(BT_SK_DEFER_SETUP,
1119 &bt_sk(sk)->flags)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001120 struct sock *parent = bt_sk(sk)->parent;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001121 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1122 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Ilia Kolomisnky05e9a2f2011-07-15 18:30:21 +00001123 if (parent)
1124 parent->sk_data_ready(parent, 0);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001125
1126 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001127 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001128 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1129 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001130 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001131 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001132 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001133 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1134 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001135 }
1136
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001137 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
1138 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001139
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001140 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001141 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001142 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001143 continue;
1144 }
1145
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001146 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001147 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001148 l2cap_build_conf_req(chan, buf), buf);
1149 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001150 }
1151
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001152 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001153 }
1154
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001155 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001156}
1157
Ido Yarivc2287682012-04-20 15:46:07 -03001158/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001159 * Returns closest match, locked.
1160 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001161static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001162 bdaddr_t *src,
1163 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001164{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001165 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001166
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001167 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001168
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001169 list_for_each_entry(c, &chan_list, global_l) {
1170 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001171
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001172 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001173 continue;
1174
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001175 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001176 int src_match, dst_match;
1177 int src_any, dst_any;
1178
Ville Tervob62f3282011-02-10 22:38:50 -03001179 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001180 src_match = !bacmp(&bt_sk(sk)->src, src);
1181 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1182 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001183 read_unlock(&chan_list_lock);
1184 return c;
1185 }
Ville Tervob62f3282011-02-10 22:38:50 -03001186
1187 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001188 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1189 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1190 if ((src_match && dst_any) || (src_any && dst_match) ||
1191 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001192 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001193 }
1194 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001195
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001196 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001197
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001198 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001199}
1200
1201static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1202{
Gustavo F. Padovanc916fbe2011-04-04 16:00:55 -03001203 struct sock *parent, *sk;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001204 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001205
1206 BT_DBG("");
1207
1208 /* Check if we have socket listening on cid */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001209 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
Ido Yarivc2287682012-04-20 15:46:07 -03001210 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001211 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001212 return;
1213
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001214 parent = pchan->sk;
1215
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001216 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001217
Gustavo Padovan80b98022012-05-27 22:27:51 -03001218 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001219 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001220 goto clean;
1221
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001222 sk = chan->sk;
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001223
Ville Tervob62f3282011-02-10 22:38:50 -03001224 hci_conn_hold(conn->hcon);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001225 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
Ville Tervob62f3282011-02-10 22:38:50 -03001226
Ville Tervob62f3282011-02-10 22:38:50 -03001227 bacpy(&bt_sk(sk)->src, conn->src);
1228 bacpy(&bt_sk(sk)->dst, conn->dst);
1229
Gustavo F. Padovand1010242011-03-25 00:39:48 -03001230 bt_accept_enqueue(parent, sk);
1231
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001232 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001233
Gustavo Padovan6754e0d2012-05-25 09:30:56 -03001234 l2cap_chan_ready(chan);
Ville Tervob62f3282011-02-10 22:38:50 -03001235
Ville Tervob62f3282011-02-10 22:38:50 -03001236clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001237 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001238}
1239
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001240static void l2cap_conn_ready(struct l2cap_conn *conn)
1241{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001242 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001243 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001244
1245 BT_DBG("conn %p", conn);
1246
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001247 if (!hcon->out && hcon->type == LE_LINK)
Ville Tervob62f3282011-02-10 22:38:50 -03001248 l2cap_le_conn_ready(conn);
1249
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001250 if (hcon->out && hcon->type == LE_LINK)
1251 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001252
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001253 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001254
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001255 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001256
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001257 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001258
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001259 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1260 l2cap_chan_unlock(chan);
1261 continue;
1262 }
1263
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001264 if (hcon->type == LE_LINK) {
1265 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001266 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001267
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001268 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001269 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001270 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001271 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001272 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001273 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001274 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001275
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001276 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001277 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001278
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001279 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001280 }
1281
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001282 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001283}
1284
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001285/* Notify sockets that we cannot guaranty reliability anymore */
1286static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1287{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001288 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001289
1290 BT_DBG("conn %p", conn);
1291
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001292 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001293
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001294 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001295 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001296 __l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001297 }
1298
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001299 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001300}
1301
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001302static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001303{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001304 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001305 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001306
Marcel Holtmann984947d2009-02-06 23:35:19 +01001307 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001308 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001309
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001310 l2cap_conn_start(conn);
1311}
1312
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001313static void l2cap_conn_del(struct hci_conn *hcon, int err)
1314{
1315 struct l2cap_conn *conn = hcon->l2cap_data;
1316 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001317
1318 if (!conn)
1319 return;
1320
1321 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1322
1323 kfree_skb(conn->rx_skb);
1324
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001325 mutex_lock(&conn->chan_lock);
1326
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001327 /* Kill channels */
1328 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001329 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001330 l2cap_chan_lock(chan);
1331
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001332 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001333
1334 l2cap_chan_unlock(chan);
1335
Gustavo Padovan80b98022012-05-27 22:27:51 -03001336 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001337 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001338 }
1339
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001340 mutex_unlock(&conn->chan_lock);
1341
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001342 hci_chan_del(conn->hchan);
1343
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001344 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001345 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001346
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001347 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001348 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001349 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001350 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001351
1352 hcon->l2cap_data = NULL;
1353 kfree(conn);
1354}
1355
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001356static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001357{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001358 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
1359 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001360
Johan Hedbergd06cc412012-06-06 18:44:11 +08001361 BT_DBG("conn %p", conn);
1362
1363 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1364 smp_chan_destroy(conn);
1365 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1366 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001367}
1368
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
1370{
Marcel Holtmann01394182006-07-03 10:02:46 +02001371 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001372 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373
Marcel Holtmann01394182006-07-03 10:02:46 +02001374 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375 return conn;
1376
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001377 hchan = hci_chan_create(hcon);
1378 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001381 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
1382 if (!conn) {
1383 hci_chan_del(hchan);
1384 return NULL;
1385 }
1386
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387 hcon->l2cap_data = conn;
1388 conn->hcon = hcon;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001389 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001390
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001391 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001392
Ville Tervoacd7d372011-02-10 22:38:49 -03001393 if (hcon->hdev->le_mtu && hcon->type == LE_LINK)
1394 conn->mtu = hcon->hdev->le_mtu;
1395 else
1396 conn->mtu = hcon->hdev->acl_mtu;
1397
Linus Torvalds1da177e2005-04-16 15:20:36 -07001398 conn->src = &hcon->hdev->bdaddr;
1399 conn->dst = &hcon->dst;
1400
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001401 conn->feat_mask = 0;
1402
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001404 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001405
1406 INIT_LIST_HEAD(&conn->chan_l);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001408 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001409 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001410 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001411 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001412
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001413 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001414
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415 return conn;
1416}
1417
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419
Ido Yarivc2287682012-04-20 15:46:07 -03001420/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421 * Returns closest match.
1422 */
Ido Yarivc2287682012-04-20 15:46:07 -03001423static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1424 bdaddr_t *src,
1425 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001427 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001429 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001430
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001431 list_for_each_entry(c, &chan_list, global_l) {
1432 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001433
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001434 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435 continue;
1436
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001437 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001438 int src_match, dst_match;
1439 int src_any, dst_any;
1440
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001442 src_match = !bacmp(&bt_sk(sk)->src, src);
1443 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1444 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001445 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001446 return c;
1447 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001448
1449 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001450 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1451 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1452 if ((src_match && dst_any) || (src_any && dst_match) ||
1453 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001454 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455 }
1456 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001457
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001458 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001459
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001460 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001461}
1462
Andre Guedes8e9f9892012-04-24 21:02:55 -03001463int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1464 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001466 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468 struct l2cap_conn *conn;
1469 struct hci_conn *hcon;
1470 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001471 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001472 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473
Andre Guedes8e9f9892012-04-24 21:02:55 -03001474 BT_DBG("%s -> %s (type %u) psm 0x%2.2x", batostr(src), batostr(dst),
Syam Sidhardhanab195162012-07-27 23:51:22 +05301475 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001476
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001477 hdev = hci_get_route(dst, src);
1478 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479 return -EHOSTUNREACH;
1480
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001481 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001482
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001483 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001484
1485 /* PSM must be odd and lsb of upper byte must be 0 */
1486 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
1487 chan->chan_type != L2CAP_CHAN_RAW) {
1488 err = -EINVAL;
1489 goto done;
1490 }
1491
1492 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1493 err = -EINVAL;
1494 goto done;
1495 }
1496
1497 switch (chan->mode) {
1498 case L2CAP_MODE_BASIC:
1499 break;
1500 case L2CAP_MODE_ERTM:
1501 case L2CAP_MODE_STREAMING:
1502 if (!disable_ertm)
1503 break;
1504 /* fall through */
1505 default:
1506 err = -ENOTSUPP;
1507 goto done;
1508 }
1509
Gustavo Padovan0797e012012-05-27 22:27:54 -03001510 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001511 case BT_CONNECT:
1512 case BT_CONNECT2:
1513 case BT_CONFIG:
1514 /* Already connecting */
1515 err = 0;
1516 goto done;
1517
1518 case BT_CONNECTED:
1519 /* Already connected */
1520 err = -EISCONN;
1521 goto done;
1522
1523 case BT_OPEN:
1524 case BT_BOUND:
1525 /* Can connect */
1526 break;
1527
1528 default:
1529 err = -EBADFD;
1530 goto done;
1531 }
1532
1533 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001534 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001535 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001536 release_sock(sk);
1537
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001538 chan->psm = psm;
1539 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001541 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001542
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001543 if (chan->dcid == L2CAP_CID_LE_DATA)
Andre Guedes8e9f9892012-04-24 21:02:55 -03001544 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001545 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001546 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001547 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001548 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001549
Ville Tervo30e76272011-02-22 16:10:53 -03001550 if (IS_ERR(hcon)) {
1551 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001553 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554
1555 conn = l2cap_conn_add(hcon, 0);
1556 if (!conn) {
1557 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001558 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559 goto done;
1560 }
1561
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001562 if (hcon->type == LE_LINK) {
1563 err = 0;
1564
1565 if (!list_empty(&conn->chan_l)) {
1566 err = -EBUSY;
1567 hci_conn_put(hcon);
1568 }
1569
1570 if (err)
1571 goto done;
1572 }
1573
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 /* Update source addr of the socket */
1575 bacpy(src, conn->src);
1576
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001577 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001578 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001579 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001580
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001581 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001582 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583
1584 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001585 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001586 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001587 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001588 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001589 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001590 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591 }
1592
Ville Tervo30e76272011-02-22 16:10:53 -03001593 err = 0;
1594
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001596 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001597 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598 hci_dev_put(hdev);
1599 return err;
1600}
1601
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001602int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001603{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001604 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001605 DECLARE_WAITQUEUE(wait, current);
1606 int err = 0;
1607 int timeo = HZ/5;
1608
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001609 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001610 set_current_state(TASK_INTERRUPTIBLE);
1611 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001612 if (!timeo)
1613 timeo = HZ/5;
1614
1615 if (signal_pending(current)) {
1616 err = sock_intr_errno(timeo);
1617 break;
1618 }
1619
1620 release_sock(sk);
1621 timeo = schedule_timeout(timeo);
1622 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001623 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001624
1625 err = sock_error(sk);
1626 if (err)
1627 break;
1628 }
1629 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001630 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001631 return err;
1632}
1633
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001634static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001635{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001636 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001637 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001638
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001639 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001640
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001641 l2cap_chan_lock(chan);
1642
Mat Martineau80909e02012-05-17 20:53:50 -07001643 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001644 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001645 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001646 return;
1647 }
1648
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001649 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001650
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001651 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001652 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001653}
1654
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001655static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001656{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001657 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001658 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001659
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001660 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001661
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001662 l2cap_chan_lock(chan);
1663
Mat Martineau80909e02012-05-17 20:53:50 -07001664 if (!chan->conn) {
1665 l2cap_chan_unlock(chan);
1666 l2cap_chan_put(chan);
1667 return;
1668 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001669
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001670 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001671 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001672 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001673}
1674
Gustavo Padovand6603662012-05-21 13:58:22 -03001675static void l2cap_streaming_send(struct l2cap_chan *chan,
1676 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001677{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001678 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001679 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001680
Mat Martineau37339372012-05-17 20:53:33 -07001681 BT_DBG("chan %p, skbs %p", chan, skbs);
1682
Mat Martineau37339372012-05-17 20:53:33 -07001683 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1684
1685 while (!skb_queue_empty(&chan->tx_q)) {
1686
1687 skb = skb_dequeue(&chan->tx_q);
1688
1689 bt_cb(skb)->control.retries = 1;
1690 control = &bt_cb(skb)->control;
1691
1692 control->reqseq = 0;
1693 control->txseq = chan->next_tx_seq;
1694
1695 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001696
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001697 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001698 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1699 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001700 }
1701
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001702 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001703
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001704 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001705
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001706 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001707 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001708 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001709}
1710
Szymon Janc67c9e842011-07-28 16:24:33 +02001711static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001712{
1713 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001714 struct l2cap_ctrl *control;
1715 int sent = 0;
1716
1717 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001718
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001719 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001720 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001721
Mat Martineau94122bb2012-05-02 09:42:02 -07001722 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1723 return 0;
1724
Mat Martineau18a48e72012-05-17 20:53:34 -07001725 while (chan->tx_send_head &&
1726 chan->unacked_frames < chan->remote_tx_win &&
1727 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001728
Mat Martineau18a48e72012-05-17 20:53:34 -07001729 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001730
Mat Martineau18a48e72012-05-17 20:53:34 -07001731 bt_cb(skb)->control.retries = 1;
1732 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001733
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001734 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001735 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001736
Mat Martineau18a48e72012-05-17 20:53:34 -07001737 control->reqseq = chan->buffer_seq;
1738 chan->last_acked_seq = chan->buffer_seq;
1739 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001740
Mat Martineau18a48e72012-05-17 20:53:34 -07001741 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001742
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001743 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001744 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1745 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001746 }
1747
Mat Martineau18a48e72012-05-17 20:53:34 -07001748 /* Clone after data has been modified. Data is assumed to be
1749 read-only (for locking purposes) on cloned sk_buffs.
1750 */
1751 tx_skb = skb_clone(skb, GFP_KERNEL);
1752
1753 if (!tx_skb)
1754 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001755
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001756 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001757
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001758 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07001759 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03001760 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07001761 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001762
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001763 if (skb_queue_is_last(&chan->tx_q, skb))
1764 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001765 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001766 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07001767
1768 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001769 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001770 }
1771
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001772 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
1773 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07001774
1775 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001776}
1777
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001778static void l2cap_ertm_resend(struct l2cap_chan *chan)
1779{
1780 struct l2cap_ctrl control;
1781 struct sk_buff *skb;
1782 struct sk_buff *tx_skb;
1783 u16 seq;
1784
1785 BT_DBG("chan %p", chan);
1786
1787 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1788 return;
1789
1790 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
1791 seq = l2cap_seq_list_pop(&chan->retrans_list);
1792
1793 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
1794 if (!skb) {
1795 BT_DBG("Error: Can't retransmit seq %d, frame missing",
1796 seq);
1797 continue;
1798 }
1799
1800 bt_cb(skb)->control.retries++;
1801 control = bt_cb(skb)->control;
1802
1803 if (chan->max_tx != 0 &&
1804 bt_cb(skb)->control.retries > chan->max_tx) {
1805 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
1806 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
1807 l2cap_seq_list_clear(&chan->retrans_list);
1808 break;
1809 }
1810
1811 control.reqseq = chan->buffer_seq;
1812 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
1813 control.final = 1;
1814 else
1815 control.final = 0;
1816
1817 if (skb_cloned(skb)) {
1818 /* Cloned sk_buffs are read-only, so we need a
1819 * writeable copy
1820 */
1821 tx_skb = skb_copy(skb, GFP_ATOMIC);
1822 } else {
1823 tx_skb = skb_clone(skb, GFP_ATOMIC);
1824 }
1825
1826 if (!tx_skb) {
1827 l2cap_seq_list_clear(&chan->retrans_list);
1828 break;
1829 }
1830
1831 /* Update skb contents */
1832 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
1833 put_unaligned_le32(__pack_extended_control(&control),
1834 tx_skb->data + L2CAP_HDR_SIZE);
1835 } else {
1836 put_unaligned_le16(__pack_enhanced_control(&control),
1837 tx_skb->data + L2CAP_HDR_SIZE);
1838 }
1839
1840 if (chan->fcs == L2CAP_FCS_CRC16) {
1841 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
1842 put_unaligned_le16(fcs, skb_put(tx_skb,
1843 L2CAP_FCS_SIZE));
1844 }
1845
1846 l2cap_do_send(chan, tx_skb);
1847
1848 BT_DBG("Resent txseq %d", control.txseq);
1849
1850 chan->last_acked_seq = chan->buffer_seq;
1851 }
1852}
1853
Mat Martineauf80842a2012-05-17 20:53:46 -07001854static void l2cap_retransmit(struct l2cap_chan *chan,
1855 struct l2cap_ctrl *control)
1856{
1857 BT_DBG("chan %p, control %p", chan, control);
1858
1859 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
1860 l2cap_ertm_resend(chan);
1861}
1862
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001863static void l2cap_retransmit_all(struct l2cap_chan *chan,
1864 struct l2cap_ctrl *control)
1865{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001866 struct sk_buff *skb;
1867
1868 BT_DBG("chan %p, control %p", chan, control);
1869
1870 if (control->poll)
1871 set_bit(CONN_SEND_FBIT, &chan->conn_state);
1872
1873 l2cap_seq_list_clear(&chan->retrans_list);
1874
1875 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1876 return;
1877
1878 if (chan->unacked_frames) {
1879 skb_queue_walk(&chan->tx_q, skb) {
1880 if (bt_cb(skb)->control.txseq == control->reqseq ||
1881 skb == chan->tx_send_head)
1882 break;
1883 }
1884
1885 skb_queue_walk_from(&chan->tx_q, skb) {
1886 if (skb == chan->tx_send_head)
1887 break;
1888
1889 l2cap_seq_list_append(&chan->retrans_list,
1890 bt_cb(skb)->control.txseq);
1891 }
1892
1893 l2cap_ertm_resend(chan);
1894 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001895}
1896
Szymon Jancb17e73b2012-01-11 10:59:47 +01001897static void l2cap_send_ack(struct l2cap_chan *chan)
1898{
Mat Martineau0a0aba42012-05-17 20:53:39 -07001899 struct l2cap_ctrl control;
1900 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
1901 chan->last_acked_seq);
1902 int threshold;
1903
1904 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
1905 chan, chan->last_acked_seq, chan->buffer_seq);
1906
1907 memset(&control, 0, sizeof(control));
1908 control.sframe = 1;
1909
1910 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
1911 chan->rx_state == L2CAP_RX_STATE_RECV) {
1912 __clear_ack_timer(chan);
1913 control.super = L2CAP_SUPER_RNR;
1914 control.reqseq = chan->buffer_seq;
1915 l2cap_send_sframe(chan, &control);
1916 } else {
1917 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
1918 l2cap_ertm_send(chan);
1919 /* If any i-frames were sent, they included an ack */
1920 if (chan->buffer_seq == chan->last_acked_seq)
1921 frames_to_ack = 0;
1922 }
1923
Mat Martineauc20f8e32012-07-10 05:47:07 -07001924 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07001925 * Calculate without mul or div
1926 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07001927 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07001928 threshold += threshold << 1;
1929 threshold >>= 2;
1930
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001931 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07001932 threshold);
1933
1934 if (frames_to_ack >= threshold) {
1935 __clear_ack_timer(chan);
1936 control.super = L2CAP_SUPER_RR;
1937 control.reqseq = chan->buffer_seq;
1938 l2cap_send_sframe(chan, &control);
1939 frames_to_ack = 0;
1940 }
1941
1942 if (frames_to_ack)
1943 __set_ack_timer(chan);
1944 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01001945}
1946
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001947static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
1948 struct msghdr *msg, int len,
1949 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02001951 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001952 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03001953 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001954
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001955 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001956 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001957
1958 sent += count;
1959 len -= count;
1960
1961 /* Continuation fragments (no L2CAP header) */
1962 frag = &skb_shinfo(skb)->frag_list;
1963 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001964 struct sk_buff *tmp;
1965
Linus Torvalds1da177e2005-04-16 15:20:36 -07001966 count = min_t(unsigned int, conn->mtu, len);
1967
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001968 tmp = chan->ops->alloc_skb(chan, count,
1969 msg->msg_flags & MSG_DONTWAIT);
1970 if (IS_ERR(tmp))
1971 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001972
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001973 *frag = tmp;
1974
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001975 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1976 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001978 (*frag)->priority = skb->priority;
1979
Linus Torvalds1da177e2005-04-16 15:20:36 -07001980 sent += count;
1981 len -= count;
1982
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03001983 skb->len += (*frag)->len;
1984 skb->data_len += (*frag)->len;
1985
Linus Torvalds1da177e2005-04-16 15:20:36 -07001986 frag = &(*frag)->next;
1987 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001988
1989 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001990}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001991
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001992static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001993 struct msghdr *msg, size_t len,
1994 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001995{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001996 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001997 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03001998 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001999 struct l2cap_hdr *lh;
2000
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002001 BT_DBG("chan %p len %zu priority %u", chan, len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002002
2003 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002004
2005 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002006 msg->msg_flags & MSG_DONTWAIT);
2007 if (IS_ERR(skb))
2008 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002009
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002010 skb->priority = priority;
2011
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002012 /* Create L2CAP header */
2013 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002014 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002015 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
2016 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002017
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002018 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002019 if (unlikely(err < 0)) {
2020 kfree_skb(skb);
2021 return ERR_PTR(err);
2022 }
2023 return skb;
2024}
2025
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002026static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002027 struct msghdr *msg, size_t len,
2028 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002029{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002030 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002031 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002032 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002033 struct l2cap_hdr *lh;
2034
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002035 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002036
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002037 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002038
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002039 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002040 msg->msg_flags & MSG_DONTWAIT);
2041 if (IS_ERR(skb))
2042 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002043
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002044 skb->priority = priority;
2045
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002046 /* Create L2CAP header */
2047 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002048 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002049 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002050
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002051 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002052 if (unlikely(err < 0)) {
2053 kfree_skb(skb);
2054 return ERR_PTR(err);
2055 }
2056 return skb;
2057}
2058
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002059static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002060 struct msghdr *msg, size_t len,
2061 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002062{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002063 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002064 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002065 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002066 struct l2cap_hdr *lh;
2067
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002068 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002069
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002070 if (!conn)
2071 return ERR_PTR(-ENOTCONN);
2072
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002073 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002074
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002075 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002076 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002077
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002078 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002079 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002080
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002081 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002082
2083 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002084 msg->msg_flags & MSG_DONTWAIT);
2085 if (IS_ERR(skb))
2086 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002087
2088 /* Create L2CAP header */
2089 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002090 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002091 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002092
Mat Martineau18a48e72012-05-17 20:53:34 -07002093 /* Control header is populated later */
2094 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2095 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2096 else
2097 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002098
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002099 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002100 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002101
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002102 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002103 if (unlikely(err < 0)) {
2104 kfree_skb(skb);
2105 return ERR_PTR(err);
2106 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002107
Mat Martineau18a48e72012-05-17 20:53:34 -07002108 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002109 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002110 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002111}
2112
Mat Martineau94122bb2012-05-02 09:42:02 -07002113static int l2cap_segment_sdu(struct l2cap_chan *chan,
2114 struct sk_buff_head *seg_queue,
2115 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002116{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002117 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002118 u16 sdu_len;
2119 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002120 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002121
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002122 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002123
Mat Martineau94122bb2012-05-02 09:42:02 -07002124 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2125 * so fragmented skbs are not used. The HCI layer's handling
2126 * of fragmented skbs is not compatible with ERTM's queueing.
2127 */
2128
2129 /* PDU size is derived from the HCI MTU */
2130 pdu_len = chan->conn->mtu;
2131
2132 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
2133
2134 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002135 if (chan->fcs)
2136 pdu_len -= L2CAP_FCS_SIZE;
2137
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002138 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002139
2140 /* Remote device may have requested smaller PDUs */
2141 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2142
2143 if (len <= pdu_len) {
2144 sar = L2CAP_SAR_UNSEGMENTED;
2145 sdu_len = 0;
2146 pdu_len = len;
2147 } else {
2148 sar = L2CAP_SAR_START;
2149 sdu_len = len;
2150 pdu_len -= L2CAP_SDULEN_SIZE;
2151 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002152
2153 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002154 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002155
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002156 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002157 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002158 return PTR_ERR(skb);
2159 }
2160
Mat Martineau94122bb2012-05-02 09:42:02 -07002161 bt_cb(skb)->control.sar = sar;
2162 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002163
Mat Martineau94122bb2012-05-02 09:42:02 -07002164 len -= pdu_len;
2165 if (sdu_len) {
2166 sdu_len = 0;
2167 pdu_len += L2CAP_SDULEN_SIZE;
2168 }
2169
2170 if (len <= pdu_len) {
2171 sar = L2CAP_SAR_END;
2172 pdu_len = len;
2173 } else {
2174 sar = L2CAP_SAR_CONTINUE;
2175 }
2176 }
2177
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002178 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002179}
2180
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002181int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
2182 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002183{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002184 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002185 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002186 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002187
2188 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002189 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002190 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002191 if (IS_ERR(skb))
2192 return PTR_ERR(skb);
2193
2194 l2cap_do_send(chan, skb);
2195 return len;
2196 }
2197
2198 switch (chan->mode) {
2199 case L2CAP_MODE_BASIC:
2200 /* Check outgoing MTU */
2201 if (len > chan->omtu)
2202 return -EMSGSIZE;
2203
2204 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002205 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002206 if (IS_ERR(skb))
2207 return PTR_ERR(skb);
2208
2209 l2cap_do_send(chan, skb);
2210 err = len;
2211 break;
2212
2213 case L2CAP_MODE_ERTM:
2214 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002215 /* Check outgoing MTU */
2216 if (len > chan->omtu) {
2217 err = -EMSGSIZE;
2218 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002219 }
2220
Mat Martineau94122bb2012-05-02 09:42:02 -07002221 __skb_queue_head_init(&seg_queue);
2222
2223 /* Do segmentation before calling in to the state machine,
2224 * since it's possible to block while waiting for memory
2225 * allocation.
2226 */
2227 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2228
2229 /* The channel could have been closed while segmenting,
2230 * check that it is still connected.
2231 */
2232 if (chan->state != BT_CONNECTED) {
2233 __skb_queue_purge(&seg_queue);
2234 err = -ENOTCONN;
2235 }
2236
2237 if (err)
2238 break;
2239
Mat Martineau37339372012-05-17 20:53:33 -07002240 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002241 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002242 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002243 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002244
Gustavo Padovand6603662012-05-21 13:58:22 -03002245 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002246
Mat Martineau94122bb2012-05-02 09:42:02 -07002247 /* If the skbs were not queued for sending, they'll still be in
2248 * seg_queue and need to be purged.
2249 */
2250 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002251 break;
2252
2253 default:
2254 BT_DBG("bad state %1.1x", chan->mode);
2255 err = -EBADFD;
2256 }
2257
2258 return err;
2259}
2260
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002261static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2262{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002263 struct l2cap_ctrl control;
2264 u16 seq;
2265
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002266 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002267
2268 memset(&control, 0, sizeof(control));
2269 control.sframe = 1;
2270 control.super = L2CAP_SUPER_SREJ;
2271
2272 for (seq = chan->expected_tx_seq; seq != txseq;
2273 seq = __next_seq(chan, seq)) {
2274 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2275 control.reqseq = seq;
2276 l2cap_send_sframe(chan, &control);
2277 l2cap_seq_list_append(&chan->srej_list, seq);
2278 }
2279 }
2280
2281 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002282}
2283
2284static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2285{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002286 struct l2cap_ctrl control;
2287
2288 BT_DBG("chan %p", chan);
2289
2290 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2291 return;
2292
2293 memset(&control, 0, sizeof(control));
2294 control.sframe = 1;
2295 control.super = L2CAP_SUPER_SREJ;
2296 control.reqseq = chan->srej_list.tail;
2297 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002298}
2299
2300static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2301{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002302 struct l2cap_ctrl control;
2303 u16 initial_head;
2304 u16 seq;
2305
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002306 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002307
2308 memset(&control, 0, sizeof(control));
2309 control.sframe = 1;
2310 control.super = L2CAP_SUPER_SREJ;
2311
2312 /* Capture initial list head to allow only one pass through the list. */
2313 initial_head = chan->srej_list.head;
2314
2315 do {
2316 seq = l2cap_seq_list_pop(&chan->srej_list);
2317 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2318 break;
2319
2320 control.reqseq = seq;
2321 l2cap_send_sframe(chan, &control);
2322 l2cap_seq_list_append(&chan->srej_list, seq);
2323 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002324}
2325
Mat Martineau608bcc62012-05-17 20:53:32 -07002326static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2327{
2328 struct sk_buff *acked_skb;
2329 u16 ackseq;
2330
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002331 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002332
2333 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2334 return;
2335
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002336 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002337 chan->expected_ack_seq, chan->unacked_frames);
2338
2339 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2340 ackseq = __next_seq(chan, ackseq)) {
2341
2342 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2343 if (acked_skb) {
2344 skb_unlink(acked_skb, &chan->tx_q);
2345 kfree_skb(acked_skb);
2346 chan->unacked_frames--;
2347 }
2348 }
2349
2350 chan->expected_ack_seq = reqseq;
2351
2352 if (chan->unacked_frames == 0)
2353 __clear_retrans_timer(chan);
2354
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002355 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002356}
2357
2358static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2359{
2360 BT_DBG("chan %p", chan);
2361
2362 chan->expected_tx_seq = chan->buffer_seq;
2363 l2cap_seq_list_clear(&chan->srej_list);
2364 skb_queue_purge(&chan->srej_q);
2365 chan->rx_state = L2CAP_RX_STATE_RECV;
2366}
2367
Gustavo Padovand6603662012-05-21 13:58:22 -03002368static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2369 struct l2cap_ctrl *control,
2370 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002371{
Mat Martineau608bcc62012-05-17 20:53:32 -07002372 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2373 event);
2374
2375 switch (event) {
2376 case L2CAP_EV_DATA_REQUEST:
2377 if (chan->tx_send_head == NULL)
2378 chan->tx_send_head = skb_peek(skbs);
2379
2380 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2381 l2cap_ertm_send(chan);
2382 break;
2383 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2384 BT_DBG("Enter LOCAL_BUSY");
2385 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2386
2387 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2388 /* The SREJ_SENT state must be aborted if we are to
2389 * enter the LOCAL_BUSY state.
2390 */
2391 l2cap_abort_rx_srej_sent(chan);
2392 }
2393
2394 l2cap_send_ack(chan);
2395
2396 break;
2397 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2398 BT_DBG("Exit LOCAL_BUSY");
2399 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2400
2401 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2402 struct l2cap_ctrl local_control;
2403
2404 memset(&local_control, 0, sizeof(local_control));
2405 local_control.sframe = 1;
2406 local_control.super = L2CAP_SUPER_RR;
2407 local_control.poll = 1;
2408 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002409 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002410
2411 chan->retry_count = 1;
2412 __set_monitor_timer(chan);
2413 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2414 }
2415 break;
2416 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2417 l2cap_process_reqseq(chan, control->reqseq);
2418 break;
2419 case L2CAP_EV_EXPLICIT_POLL:
2420 l2cap_send_rr_or_rnr(chan, 1);
2421 chan->retry_count = 1;
2422 __set_monitor_timer(chan);
2423 __clear_ack_timer(chan);
2424 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2425 break;
2426 case L2CAP_EV_RETRANS_TO:
2427 l2cap_send_rr_or_rnr(chan, 1);
2428 chan->retry_count = 1;
2429 __set_monitor_timer(chan);
2430 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2431 break;
2432 case L2CAP_EV_RECV_FBIT:
2433 /* Nothing to process */
2434 break;
2435 default:
2436 break;
2437 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002438}
2439
Gustavo Padovand6603662012-05-21 13:58:22 -03002440static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2441 struct l2cap_ctrl *control,
2442 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002443{
Mat Martineau608bcc62012-05-17 20:53:32 -07002444 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2445 event);
2446
2447 switch (event) {
2448 case L2CAP_EV_DATA_REQUEST:
2449 if (chan->tx_send_head == NULL)
2450 chan->tx_send_head = skb_peek(skbs);
2451 /* Queue data, but don't send. */
2452 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2453 break;
2454 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2455 BT_DBG("Enter LOCAL_BUSY");
2456 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2457
2458 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2459 /* The SREJ_SENT state must be aborted if we are to
2460 * enter the LOCAL_BUSY state.
2461 */
2462 l2cap_abort_rx_srej_sent(chan);
2463 }
2464
2465 l2cap_send_ack(chan);
2466
2467 break;
2468 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2469 BT_DBG("Exit LOCAL_BUSY");
2470 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2471
2472 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2473 struct l2cap_ctrl local_control;
2474 memset(&local_control, 0, sizeof(local_control));
2475 local_control.sframe = 1;
2476 local_control.super = L2CAP_SUPER_RR;
2477 local_control.poll = 1;
2478 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002479 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002480
2481 chan->retry_count = 1;
2482 __set_monitor_timer(chan);
2483 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2484 }
2485 break;
2486 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2487 l2cap_process_reqseq(chan, control->reqseq);
2488
2489 /* Fall through */
2490
2491 case L2CAP_EV_RECV_FBIT:
2492 if (control && control->final) {
2493 __clear_monitor_timer(chan);
2494 if (chan->unacked_frames > 0)
2495 __set_retrans_timer(chan);
2496 chan->retry_count = 0;
2497 chan->tx_state = L2CAP_TX_STATE_XMIT;
2498 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2499 }
2500 break;
2501 case L2CAP_EV_EXPLICIT_POLL:
2502 /* Ignore */
2503 break;
2504 case L2CAP_EV_MONITOR_TO:
2505 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2506 l2cap_send_rr_or_rnr(chan, 1);
2507 __set_monitor_timer(chan);
2508 chan->retry_count++;
2509 } else {
2510 l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
2511 }
2512 break;
2513 default:
2514 break;
2515 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002516}
2517
Gustavo Padovand6603662012-05-21 13:58:22 -03002518static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2519 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002520{
Mat Martineau608bcc62012-05-17 20:53:32 -07002521 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2522 chan, control, skbs, event, chan->tx_state);
2523
2524 switch (chan->tx_state) {
2525 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002526 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002527 break;
2528 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002529 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002530 break;
2531 default:
2532 /* Ignore event */
2533 break;
2534 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002535}
2536
Mat Martineau4b51dae92012-05-17 20:53:37 -07002537static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2538 struct l2cap_ctrl *control)
2539{
2540 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002541 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002542}
2543
Mat Martineauf80842a2012-05-17 20:53:46 -07002544static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2545 struct l2cap_ctrl *control)
2546{
2547 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002548 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002549}
2550
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551/* Copy frame to all raw sockets on that connection */
2552static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2553{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002554 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002555 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002556
2557 BT_DBG("conn %p", conn);
2558
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002559 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002560
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002561 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002562 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002563 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002564 continue;
2565
2566 /* Don't send frame to the socket it came from */
2567 if (skb->sk == sk)
2568 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002569 nskb = skb_clone(skb, GFP_ATOMIC);
2570 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002571 continue;
2572
Gustavo Padovan80b98022012-05-27 22:27:51 -03002573 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002574 kfree_skb(nskb);
2575 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002576
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002577 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002578}
2579
2580/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002581static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2582 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002583{
2584 struct sk_buff *skb, **frag;
2585 struct l2cap_cmd_hdr *cmd;
2586 struct l2cap_hdr *lh;
2587 int len, count;
2588
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002589 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2590 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002591
2592 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2593 count = min_t(unsigned int, conn->mtu, len);
2594
2595 skb = bt_skb_alloc(count, GFP_ATOMIC);
2596 if (!skb)
2597 return NULL;
2598
2599 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002600 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002601
2602 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002603 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002604 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002605 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002606
2607 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2608 cmd->code = code;
2609 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002610 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002611
2612 if (dlen) {
2613 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2614 memcpy(skb_put(skb, count), data, count);
2615 data += count;
2616 }
2617
2618 len -= skb->len;
2619
2620 /* Continuation fragments (no L2CAP header) */
2621 frag = &skb_shinfo(skb)->frag_list;
2622 while (len) {
2623 count = min_t(unsigned int, conn->mtu, len);
2624
2625 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2626 if (!*frag)
2627 goto fail;
2628
2629 memcpy(skb_put(*frag, count), data, count);
2630
2631 len -= count;
2632 data += count;
2633
2634 frag = &(*frag)->next;
2635 }
2636
2637 return skb;
2638
2639fail:
2640 kfree_skb(skb);
2641 return NULL;
2642}
2643
2644static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2645{
2646 struct l2cap_conf_opt *opt = *ptr;
2647 int len;
2648
2649 len = L2CAP_CONF_OPT_SIZE + opt->len;
2650 *ptr += len;
2651
2652 *type = opt->type;
2653 *olen = opt->len;
2654
2655 switch (opt->len) {
2656 case 1:
2657 *val = *((u8 *) opt->val);
2658 break;
2659
2660 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002661 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662 break;
2663
2664 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002665 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002666 break;
2667
2668 default:
2669 *val = (unsigned long) opt->val;
2670 break;
2671 }
2672
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002673 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002674 return len;
2675}
2676
Linus Torvalds1da177e2005-04-16 15:20:36 -07002677static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2678{
2679 struct l2cap_conf_opt *opt = *ptr;
2680
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002681 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002682
2683 opt->type = type;
2684 opt->len = len;
2685
2686 switch (len) {
2687 case 1:
2688 *((u8 *) opt->val) = val;
2689 break;
2690
2691 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002692 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002693 break;
2694
2695 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002696 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002697 break;
2698
2699 default:
2700 memcpy(opt->val, (void *) val, len);
2701 break;
2702 }
2703
2704 *ptr += L2CAP_CONF_OPT_SIZE + len;
2705}
2706
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002707static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2708{
2709 struct l2cap_conf_efs efs;
2710
Szymon Janc1ec918c2011-11-16 09:32:21 +01002711 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002712 case L2CAP_MODE_ERTM:
2713 efs.id = chan->local_id;
2714 efs.stype = chan->local_stype;
2715 efs.msdu = cpu_to_le16(chan->local_msdu);
2716 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002717 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
2718 efs.flush_to = __constant_cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002719 break;
2720
2721 case L2CAP_MODE_STREAMING:
2722 efs.id = 1;
2723 efs.stype = L2CAP_SERV_BESTEFFORT;
2724 efs.msdu = cpu_to_le16(chan->local_msdu);
2725 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2726 efs.acc_lat = 0;
2727 efs.flush_to = 0;
2728 break;
2729
2730 default:
2731 return;
2732 }
2733
2734 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
2735 (unsigned long) &efs);
2736}
2737
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002738static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002739{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002740 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07002741 ack_timer.work);
2742 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002743
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02002744 BT_DBG("chan %p", chan);
2745
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002746 l2cap_chan_lock(chan);
2747
Mat Martineau03625202012-05-17 20:53:51 -07002748 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2749 chan->last_acked_seq);
2750
2751 if (frames_to_ack)
2752 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002753
2754 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01002755 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002756}
2757
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03002758int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002759{
Mat Martineau3c588192012-04-11 10:48:42 -07002760 int err;
2761
Mat Martineau105bdf92012-04-27 16:50:48 -07002762 chan->next_tx_seq = 0;
2763 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002764 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002765 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002766 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002767 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07002768 chan->last_acked_seq = 0;
2769 chan->sdu = NULL;
2770 chan->sdu_last_frag = NULL;
2771 chan->sdu_len = 0;
2772
Mat Martineaud34c34f2012-05-14 14:49:27 -07002773 skb_queue_head_init(&chan->tx_q);
2774
Mat Martineau105bdf92012-04-27 16:50:48 -07002775 if (chan->mode != L2CAP_MODE_ERTM)
2776 return 0;
2777
2778 chan->rx_state = L2CAP_RX_STATE_RECV;
2779 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002780
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002781 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
2782 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
2783 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002784
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03002785 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002786
Mat Martineau3c588192012-04-11 10:48:42 -07002787 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
2788 if (err < 0)
2789 return err;
2790
Mat Martineau9dc9aff2012-05-17 16:20:14 -07002791 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
2792 if (err < 0)
2793 l2cap_seq_list_free(&chan->srej_list);
2794
2795 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002796}
2797
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002798static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2799{
2800 switch (mode) {
2801 case L2CAP_MODE_STREAMING:
2802 case L2CAP_MODE_ERTM:
2803 if (l2cap_mode_supported(mode, remote_feat_mask))
2804 return mode;
2805 /* fall through */
2806 default:
2807 return L2CAP_MODE_BASIC;
2808 }
2809}
2810
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002811static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
2812{
2813 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
2814}
2815
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002816static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
2817{
2818 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
2819}
2820
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002821static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
2822{
2823 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002824 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002825 /* use extended control field */
2826 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002827 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
2828 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002829 chan->tx_win = min_t(u16, chan->tx_win,
2830 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002831 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
2832 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07002833 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002834}
2835
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03002836static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002837{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002838 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002839 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002840 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002841 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002842
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03002843 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002844
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002845 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002846 goto done;
2847
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002848 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002849 case L2CAP_MODE_STREAMING:
2850 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002851 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002852 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002853
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002854 if (__l2cap_efs_supported(chan))
2855 set_bit(FLAG_EFS_ENABLE, &chan->flags);
2856
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002857 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002858 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002859 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002860 break;
2861 }
2862
2863done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002864 if (chan->imtu != L2CAP_DEFAULT_MTU)
2865 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02002866
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002867 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002868 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002869 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
2870 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002871 break;
2872
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002873 rfc.mode = L2CAP_MODE_BASIC;
2874 rfc.txwin_size = 0;
2875 rfc.max_transmit = 0;
2876 rfc.retrans_timeout = 0;
2877 rfc.monitor_timeout = 0;
2878 rfc.max_pdu_size = 0;
2879
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002880 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2881 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002882 break;
2883
2884 case L2CAP_MODE_ERTM:
2885 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002886 rfc.max_transmit = chan->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002887 rfc.retrans_timeout = 0;
2888 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002889
2890 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
2891 L2CAP_EXT_HDR_SIZE -
2892 L2CAP_SDULEN_SIZE -
2893 L2CAP_FCS_SIZE);
2894 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002895
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002896 l2cap_txwin_setup(chan);
2897
2898 rfc.txwin_size = min_t(u16, chan->tx_win,
2899 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002900
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002901 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2902 (unsigned long) &rfc);
2903
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002904 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2905 l2cap_add_opt_efs(&ptr, chan);
2906
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002907 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002908 break;
2909
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002910 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002911 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002912 chan->fcs = L2CAP_FCS_NONE;
2913 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002914 }
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002915
2916 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2917 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
2918 chan->tx_win);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002919 break;
2920
2921 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07002922 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002923 rfc.mode = L2CAP_MODE_STREAMING;
2924 rfc.txwin_size = 0;
2925 rfc.max_transmit = 0;
2926 rfc.retrans_timeout = 0;
2927 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002928
2929 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
2930 L2CAP_EXT_HDR_SIZE -
2931 L2CAP_SDULEN_SIZE -
2932 L2CAP_FCS_SIZE);
2933 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002934
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002935 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2936 (unsigned long) &rfc);
2937
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002938 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2939 l2cap_add_opt_efs(&ptr, chan);
2940
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002941 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002942 break;
2943
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002944 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002945 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002946 chan->fcs = L2CAP_FCS_NONE;
2947 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002948 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002949 break;
2950 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002951
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002952 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03002953 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002954
2955 return ptr - data;
2956}
2957
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002958static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002959{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002960 struct l2cap_conf_rsp *rsp = data;
2961 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002962 void *req = chan->conf_req;
2963 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002964 int type, hint, olen;
2965 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002966 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002967 struct l2cap_conf_efs efs;
2968 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02002969 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002970 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002971 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002972
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002973 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002974
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002975 while (len >= L2CAP_CONF_OPT_SIZE) {
2976 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002977
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002978 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002979 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002980
2981 switch (type) {
2982 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002983 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002984 break;
2985
2986 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002987 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002988 break;
2989
2990 case L2CAP_CONF_QOS:
2991 break;
2992
Marcel Holtmann6464f352007-10-20 13:39:51 +02002993 case L2CAP_CONF_RFC:
2994 if (olen == sizeof(rfc))
2995 memcpy(&rfc, (void *) val, olen);
2996 break;
2997
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002998 case L2CAP_CONF_FCS:
2999 if (val == L2CAP_FCS_NONE)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003000 set_bit(CONF_NO_FCS_RECV, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003001 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003002
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003003 case L2CAP_CONF_EFS:
3004 remote_efs = 1;
3005 if (olen == sizeof(efs))
3006 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003007 break;
3008
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003009 case L2CAP_CONF_EWS:
3010 if (!enable_hs)
3011 return -ECONNREFUSED;
3012
3013 set_bit(FLAG_EXT_CTRL, &chan->flags);
3014 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003015 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003016 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003017 break;
3018
3019 default:
3020 if (hint)
3021 break;
3022
3023 result = L2CAP_CONF_UNKNOWN;
3024 *((u8 *) ptr++) = type;
3025 break;
3026 }
3027 }
3028
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003029 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003030 goto done;
3031
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003032 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003033 case L2CAP_MODE_STREAMING:
3034 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003035 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003036 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003037 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003038 break;
3039 }
3040
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003041 if (remote_efs) {
3042 if (__l2cap_efs_supported(chan))
3043 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3044 else
3045 return -ECONNREFUSED;
3046 }
3047
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003048 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003049 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003050
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003051 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003052 }
3053
3054done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003055 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003056 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003057 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003058
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003059 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003060 return -ECONNREFUSED;
3061
3062 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3063 sizeof(rfc), (unsigned long) &rfc);
3064 }
3065
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003066 if (result == L2CAP_CONF_SUCCESS) {
3067 /* Configure output options and let the other side know
3068 * which ones we don't like. */
3069
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003070 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3071 result = L2CAP_CONF_UNACCEPT;
3072 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003073 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003074 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003075 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003076 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003077
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003078 if (remote_efs) {
3079 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
3080 efs.stype != L2CAP_SERV_NOTRAFIC &&
3081 efs.stype != chan->local_stype) {
3082
3083 result = L2CAP_CONF_UNACCEPT;
3084
3085 if (chan->num_conf_req >= 1)
3086 return -ECONNREFUSED;
3087
3088 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003089 sizeof(efs),
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003090 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003091 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003092 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003093 result = L2CAP_CONF_PENDING;
3094 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003095 }
3096 }
3097
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003098 switch (rfc.mode) {
3099 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003100 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003101 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003102 break;
3103
3104 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003105 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3106 chan->remote_tx_win = rfc.txwin_size;
3107 else
3108 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3109
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003110 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003111
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003112 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
3113 chan->conn->mtu -
3114 L2CAP_EXT_HDR_SIZE -
3115 L2CAP_SDULEN_SIZE -
3116 L2CAP_FCS_SIZE);
3117 rfc.max_pdu_size = cpu_to_le16(size);
3118 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003119
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003120 rfc.retrans_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003121 __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003122 rfc.monitor_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003123 __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003124
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003125 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003126
3127 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3128 sizeof(rfc), (unsigned long) &rfc);
3129
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003130 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3131 chan->remote_id = efs.id;
3132 chan->remote_stype = efs.stype;
3133 chan->remote_msdu = le16_to_cpu(efs.msdu);
3134 chan->remote_flush_to =
3135 le32_to_cpu(efs.flush_to);
3136 chan->remote_acc_lat =
3137 le32_to_cpu(efs.acc_lat);
3138 chan->remote_sdu_itime =
3139 le32_to_cpu(efs.sdu_itime);
3140 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
3141 sizeof(efs), (unsigned long) &efs);
3142 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003143 break;
3144
3145 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003146 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
3147 chan->conn->mtu -
3148 L2CAP_EXT_HDR_SIZE -
3149 L2CAP_SDULEN_SIZE -
3150 L2CAP_FCS_SIZE);
3151 rfc.max_pdu_size = cpu_to_le16(size);
3152 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003153
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003154 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003155
3156 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3157 sizeof(rfc), (unsigned long) &rfc);
3158
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003159 break;
3160
3161 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003162 result = L2CAP_CONF_UNACCEPT;
3163
3164 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003165 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003166 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003167
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003168 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003169 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003170 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003171 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003172 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003173 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003174
3175 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003176}
3177
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003178static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003179{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003180 struct l2cap_conf_req *req = data;
3181 void *ptr = req->data;
3182 int type, olen;
3183 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003184 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003185 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003186
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003187 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003188
3189 while (len >= L2CAP_CONF_OPT_SIZE) {
3190 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3191
3192 switch (type) {
3193 case L2CAP_CONF_MTU:
3194 if (val < L2CAP_DEFAULT_MIN_MTU) {
3195 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003196 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003197 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003198 chan->imtu = val;
3199 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003200 break;
3201
3202 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003203 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003204 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003205 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003206 break;
3207
3208 case L2CAP_CONF_RFC:
3209 if (olen == sizeof(rfc))
3210 memcpy(&rfc, (void *)val, olen);
3211
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003212 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003213 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003214 return -ECONNREFUSED;
3215
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003216 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003217
3218 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3219 sizeof(rfc), (unsigned long) &rfc);
3220 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003221
3222 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003223 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003224 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003225 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003226 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003227
3228 case L2CAP_CONF_EFS:
3229 if (olen == sizeof(efs))
3230 memcpy(&efs, (void *)val, olen);
3231
3232 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
3233 efs.stype != L2CAP_SERV_NOTRAFIC &&
3234 efs.stype != chan->local_stype)
3235 return -ECONNREFUSED;
3236
3237 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
3238 sizeof(efs), (unsigned long) &efs);
3239 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003240 }
3241 }
3242
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003243 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003244 return -ECONNREFUSED;
3245
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003246 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003247
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003248 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003249 switch (rfc.mode) {
3250 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003251 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3252 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3253 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003254 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3255 chan->ack_win = min_t(u16, chan->ack_win,
3256 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003257
3258 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3259 chan->local_msdu = le16_to_cpu(efs.msdu);
3260 chan->local_sdu_itime =
3261 le32_to_cpu(efs.sdu_itime);
3262 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3263 chan->local_flush_to =
3264 le32_to_cpu(efs.flush_to);
3265 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003266 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003267
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003268 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003269 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003270 }
3271 }
3272
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003273 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003274 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003275
3276 return ptr - data;
3277}
3278
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003279static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003280{
3281 struct l2cap_conf_rsp *rsp = data;
3282 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003283
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003284 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003285
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003286 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003287 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003288 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003289
3290 return ptr - data;
3291}
3292
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003293void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003294{
3295 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003296 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003297 u8 buf[128];
3298
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003299 rsp.scid = cpu_to_le16(chan->dcid);
3300 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003301 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3302 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003303 l2cap_send_cmd(conn, chan->ident,
3304 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
3305
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003306 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003307 return;
3308
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003309 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3310 l2cap_build_conf_req(chan, buf), buf);
3311 chan->num_conf_req++;
3312}
3313
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003314static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003315{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003316 int type, olen;
3317 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003318 /* Use sane default values in case a misbehaving remote device
3319 * did not send an RFC or extended window size option.
3320 */
3321 u16 txwin_ext = chan->ack_win;
3322 struct l2cap_conf_rfc rfc = {
3323 .mode = chan->mode,
3324 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3325 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3326 .max_pdu_size = cpu_to_le16(chan->imtu),
3327 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3328 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003329
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003330 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003331
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003332 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003333 return;
3334
3335 while (len >= L2CAP_CONF_OPT_SIZE) {
3336 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3337
Mat Martineauc20f8e32012-07-10 05:47:07 -07003338 switch (type) {
3339 case L2CAP_CONF_RFC:
3340 if (olen == sizeof(rfc))
3341 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003342 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003343 case L2CAP_CONF_EWS:
3344 txwin_ext = val;
3345 break;
3346 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003347 }
3348
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003349 switch (rfc.mode) {
3350 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003351 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3352 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003353 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3354 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3355 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3356 else
3357 chan->ack_win = min_t(u16, chan->ack_win,
3358 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003359 break;
3360 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003361 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003362 }
3363}
3364
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003365static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3366{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003367 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003368
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003369 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003370 return 0;
3371
3372 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
3373 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003374 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003375
3376 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003377 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003378
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003379 l2cap_conn_start(conn);
3380 }
3381
3382 return 0;
3383}
3384
Linus Torvalds1da177e2005-04-16 15:20:36 -07003385static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3386{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003387 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3388 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003389 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003390 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003391 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003392
3393 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003394 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003395
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003396 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003397
3398 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003399 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003400 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003401 result = L2CAP_CR_BAD_PSM;
3402 goto sendresp;
3403 }
3404
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003405 parent = pchan->sk;
3406
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003407 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003408 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003409
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003410 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003411 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003412 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003413 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003414 result = L2CAP_CR_SEC_BLOCK;
3415 goto response;
3416 }
3417
Linus Torvalds1da177e2005-04-16 15:20:36 -07003418 result = L2CAP_CR_NO_MEM;
3419
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003420 /* Check if we already have channel with that dcid */
3421 if (__l2cap_get_chan_by_dcid(conn, scid))
3422 goto response;
3423
Gustavo Padovan80b98022012-05-27 22:27:51 -03003424 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003425 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003426 goto response;
3427
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003428 sk = chan->sk;
3429
Linus Torvalds1da177e2005-04-16 15:20:36 -07003430 hci_conn_hold(conn->hcon);
3431
Linus Torvalds1da177e2005-04-16 15:20:36 -07003432 bacpy(&bt_sk(sk)->src, conn->src);
3433 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003434 chan->psm = psm;
3435 chan->dcid = scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003436
Gustavo F. Padovand1010242011-03-25 00:39:48 -03003437 bt_accept_enqueue(parent, sk);
3438
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003439 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003440
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003441 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003442
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003443 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003444
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003445 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003446
Marcel Holtmann984947d2009-02-06 23:35:19 +01003447 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003448 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003449 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003450 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003451 result = L2CAP_CR_PEND;
3452 status = L2CAP_CS_AUTHOR_PEND;
3453 parent->sk_data_ready(parent, 0);
3454 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003455 __l2cap_state_change(chan, BT_CONFIG);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003456 result = L2CAP_CR_SUCCESS;
3457 status = L2CAP_CS_NO_INFO;
3458 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003459 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003460 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003461 result = L2CAP_CR_PEND;
3462 status = L2CAP_CS_AUTHEN_PEND;
3463 }
3464 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003465 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003466 result = L2CAP_CR_PEND;
3467 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003468 }
3469
Linus Torvalds1da177e2005-04-16 15:20:36 -07003470response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003471 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003472 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003473
3474sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003475 rsp.scid = cpu_to_le16(scid);
3476 rsp.dcid = cpu_to_le16(dcid);
3477 rsp.result = cpu_to_le16(result);
3478 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003479 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003480
3481 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3482 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003483 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003484
3485 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3486 conn->info_ident = l2cap_get_ident(conn);
3487
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003488 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003489
3490 l2cap_send_cmd(conn, conn->info_ident,
3491 L2CAP_INFO_REQ, sizeof(info), &info);
3492 }
3493
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003494 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003495 result == L2CAP_CR_SUCCESS) {
3496 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003497 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003498 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003499 l2cap_build_conf_req(chan, buf), buf);
3500 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003501 }
3502
Linus Torvalds1da177e2005-04-16 15:20:36 -07003503 return 0;
3504}
3505
3506static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3507{
3508 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3509 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003510 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003511 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003512 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003513
3514 scid = __le16_to_cpu(rsp->scid);
3515 dcid = __le16_to_cpu(rsp->dcid);
3516 result = __le16_to_cpu(rsp->result);
3517 status = __le16_to_cpu(rsp->status);
3518
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003519 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x",
3520 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003521
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003522 mutex_lock(&conn->chan_lock);
3523
Linus Torvalds1da177e2005-04-16 15:20:36 -07003524 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003525 chan = __l2cap_get_chan_by_scid(conn, scid);
3526 if (!chan) {
3527 err = -EFAULT;
3528 goto unlock;
3529 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003530 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003531 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3532 if (!chan) {
3533 err = -EFAULT;
3534 goto unlock;
3535 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003536 }
3537
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003538 err = 0;
3539
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003540 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003541
Linus Torvalds1da177e2005-04-16 15:20:36 -07003542 switch (result) {
3543 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003544 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003545 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003546 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003547 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003548
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003549 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003550 break;
3551
Linus Torvalds1da177e2005-04-16 15:20:36 -07003552 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003553 l2cap_build_conf_req(chan, req), req);
3554 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003555 break;
3556
3557 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003558 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003559 break;
3560
3561 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003562 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003563 break;
3564 }
3565
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003566 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003567
3568unlock:
3569 mutex_unlock(&conn->chan_lock);
3570
3571 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003572}
3573
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003574static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003575{
3576 /* FCS is enabled only in ERTM or streaming mode, if one or both
3577 * sides request it.
3578 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003579 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003580 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003581 else if (!test_bit(CONF_NO_FCS_RECV, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003582 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003583}
3584
Al Viro88219a02007-07-29 00:17:25 -07003585static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003586{
3587 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3588 u16 dcid, flags;
3589 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003590 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003591 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003592
3593 dcid = __le16_to_cpu(req->dcid);
3594 flags = __le16_to_cpu(req->flags);
3595
3596 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3597
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003598 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003599 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003600 return -ENOENT;
3601
David S. Miller033b1142011-07-21 13:38:42 -07003602 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003603 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003604
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003605 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003606 rej.scid = cpu_to_le16(chan->scid);
3607 rej.dcid = cpu_to_le16(chan->dcid);
3608
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003609 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
3610 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003611 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003612 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003613
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003614 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003615 len = cmd_len - sizeof(*req);
Dan Rosenberg7ac28812011-06-24 08:38:05 -04003616 if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003617 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003618 l2cap_build_conf_rsp(chan, rsp,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003619 L2CAP_CONF_REJECT, flags), rsp);
3620 goto unlock;
3621 }
3622
3623 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003624 memcpy(chan->conf_req + chan->conf_len, req->data, len);
3625 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003626
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003627 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003628 /* Incomplete config. Send empty response. */
3629 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003630 l2cap_build_conf_rsp(chan, rsp,
Andrei Emeltchenko5325e5b2012-05-23 11:31:22 +03003631 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003632 goto unlock;
3633 }
3634
3635 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003636 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003637 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003638 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003639 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003640 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003641
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003642 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003643 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003644
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003645 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003646 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003647
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003648 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02003649 goto unlock;
3650
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003651 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003652 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003653
Mat Martineau105bdf92012-04-27 16:50:48 -07003654 if (chan->mode == L2CAP_MODE_ERTM ||
3655 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003656 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003657
Mat Martineau3c588192012-04-11 10:48:42 -07003658 if (err < 0)
3659 l2cap_send_disconn_req(chan->conn, chan, -err);
3660 else
3661 l2cap_chan_ready(chan);
3662
Marcel Holtmann876d9482007-10-20 13:35:42 +02003663 goto unlock;
3664 }
3665
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003666 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003667 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003668 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003669 l2cap_build_conf_req(chan, buf), buf);
3670 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003671 }
3672
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003673 /* Got Conf Rsp PENDING from remote side and asume we sent
3674 Conf Rsp PENDING in the code above */
3675 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
3676 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3677
3678 /* check compatibility */
3679
3680 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3681 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3682
3683 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003684 l2cap_build_conf_rsp(chan, rsp,
Andrei Emeltchenko5325e5b2012-05-23 11:31:22 +03003685 L2CAP_CONF_SUCCESS, flags), rsp);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003686 }
3687
Linus Torvalds1da177e2005-04-16 15:20:36 -07003688unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003689 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003690 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003691}
3692
3693static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3694{
3695 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3696 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003697 struct l2cap_chan *chan;
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003698 int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07003699 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003700
3701 scid = __le16_to_cpu(rsp->scid);
3702 flags = __le16_to_cpu(rsp->flags);
3703 result = __le16_to_cpu(rsp->result);
3704
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003705 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
3706 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003707
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003708 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003709 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003710 return 0;
3711
3712 switch (result) {
3713 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003714 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003715 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003716 break;
3717
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003718 case L2CAP_CONF_PENDING:
3719 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
3720
3721 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3722 char buf[64];
3723
3724 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3725 buf, &result);
3726 if (len < 0) {
3727 l2cap_send_disconn_req(conn, chan, ECONNRESET);
3728 goto done;
3729 }
3730
3731 /* check compatibility */
3732
3733 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3734 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3735
3736 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003737 l2cap_build_conf_rsp(chan, buf,
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003738 L2CAP_CONF_SUCCESS, 0x0000), buf);
3739 }
3740 goto done;
3741
Linus Torvalds1da177e2005-04-16 15:20:36 -07003742 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003743 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003744 char req[64];
3745
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003746 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003747 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003748 goto done;
3749 }
3750
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003751 /* throw out any old stored conf requests */
3752 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003753 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3754 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003755 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003756 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003757 goto done;
3758 }
3759
3760 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3761 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003762 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003763 if (result != L2CAP_CONF_SUCCESS)
3764 goto done;
3765 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003766 }
3767
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003768 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003769 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02003770
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003771 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
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 done;
3774 }
3775
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003776 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003777 goto done;
3778
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003779 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003780
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003781 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003782 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003783
Mat Martineau105bdf92012-04-27 16:50:48 -07003784 if (chan->mode == L2CAP_MODE_ERTM ||
3785 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003786 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003787
Mat Martineau3c588192012-04-11 10:48:42 -07003788 if (err < 0)
3789 l2cap_send_disconn_req(chan->conn, chan, -err);
3790 else
3791 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003792 }
3793
3794done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003795 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003796 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003797}
3798
3799static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3800{
3801 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3802 struct l2cap_disconn_rsp rsp;
3803 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003804 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003805 struct sock *sk;
3806
3807 scid = __le16_to_cpu(req->scid);
3808 dcid = __le16_to_cpu(req->dcid);
3809
3810 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3811
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003812 mutex_lock(&conn->chan_lock);
3813
3814 chan = __l2cap_get_chan_by_scid(conn, dcid);
3815 if (!chan) {
3816 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003817 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003818 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003819
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003820 l2cap_chan_lock(chan);
3821
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003822 sk = chan->sk;
3823
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003824 rsp.dcid = cpu_to_le16(chan->scid);
3825 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003826 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3827
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003828 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003829 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003830 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003831
Mat Martineau61d6ef32012-04-27 16:50:50 -07003832 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003833 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003834
3835 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003836
Gustavo Padovan80b98022012-05-27 22:27:51 -03003837 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003838 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003839
3840 mutex_unlock(&conn->chan_lock);
3841
Linus Torvalds1da177e2005-04-16 15:20:36 -07003842 return 0;
3843}
3844
3845static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3846{
3847 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3848 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003849 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003850
3851 scid = __le16_to_cpu(rsp->scid);
3852 dcid = __le16_to_cpu(rsp->dcid);
3853
3854 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3855
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003856 mutex_lock(&conn->chan_lock);
3857
3858 chan = __l2cap_get_chan_by_scid(conn, scid);
3859 if (!chan) {
3860 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003861 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003862 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003863
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003864 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003865
Mat Martineau61d6ef32012-04-27 16:50:50 -07003866 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003867 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003868
3869 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003870
Gustavo Padovan80b98022012-05-27 22:27:51 -03003871 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003872 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003873
3874 mutex_unlock(&conn->chan_lock);
3875
Linus Torvalds1da177e2005-04-16 15:20:36 -07003876 return 0;
3877}
3878
3879static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3880{
3881 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003882 u16 type;
3883
3884 type = __le16_to_cpu(req->type);
3885
3886 BT_DBG("type 0x%4.4x", type);
3887
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003888 if (type == L2CAP_IT_FEAT_MASK) {
3889 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003890 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003891 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003892 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
3893 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03003894 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003895 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3896 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003897 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003898 feat_mask |= L2CAP_FEAT_EXT_FLOW
3899 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003900
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003901 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003902 l2cap_send_cmd(conn, cmd->ident,
3903 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003904 } else if (type == L2CAP_IT_FIXED_CHAN) {
3905 u8 buf[12];
3906 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07003907
3908 if (enable_hs)
3909 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
3910 else
3911 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
3912
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003913 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3914 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03003915 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003916 l2cap_send_cmd(conn, cmd->ident,
3917 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003918 } else {
3919 struct l2cap_info_rsp rsp;
3920 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003921 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003922 l2cap_send_cmd(conn, cmd->ident,
3923 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3924 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003925
3926 return 0;
3927}
3928
3929static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3930{
3931 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3932 u16 type, result;
3933
3934 type = __le16_to_cpu(rsp->type);
3935 result = __le16_to_cpu(rsp->result);
3936
3937 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3938
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02003939 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
3940 if (cmd->ident != conn->info_ident ||
3941 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
3942 return 0;
3943
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003944 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003945
Ville Tervoadb08ed2010-08-04 09:43:33 +03003946 if (result != L2CAP_IR_SUCCESS) {
3947 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3948 conn->info_ident = 0;
3949
3950 l2cap_conn_start(conn);
3951
3952 return 0;
3953 }
3954
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003955 switch (type) {
3956 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07003957 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003958
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003959 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003960 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003961 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003962
3963 conn->info_ident = l2cap_get_ident(conn);
3964
3965 l2cap_send_cmd(conn, conn->info_ident,
3966 L2CAP_INFO_REQ, sizeof(req), &req);
3967 } else {
3968 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3969 conn->info_ident = 0;
3970
3971 l2cap_conn_start(conn);
3972 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003973 break;
3974
3975 case L2CAP_IT_FIXED_CHAN:
3976 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01003977 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003978 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003979
3980 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003981 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003982 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003983
Linus Torvalds1da177e2005-04-16 15:20:36 -07003984 return 0;
3985}
3986
Mat Martineauf94ff6f2011-11-02 16:18:32 -07003987static inline int l2cap_create_channel_req(struct l2cap_conn *conn,
3988 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3989 void *data)
3990{
3991 struct l2cap_create_chan_req *req = data;
3992 struct l2cap_create_chan_rsp rsp;
3993 u16 psm, scid;
3994
3995 if (cmd_len != sizeof(*req))
3996 return -EPROTO;
3997
3998 if (!enable_hs)
3999 return -EINVAL;
4000
4001 psm = le16_to_cpu(req->psm);
4002 scid = le16_to_cpu(req->scid);
4003
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004004 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 -07004005
4006 /* Placeholder: Always reject */
4007 rsp.dcid = 0;
4008 rsp.scid = cpu_to_le16(scid);
Andrei Emeltchenko8ce0c492012-03-12 12:13:09 +02004009 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4010 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004011
4012 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4013 sizeof(rsp), &rsp);
4014
4015 return 0;
4016}
4017
4018static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn,
4019 struct l2cap_cmd_hdr *cmd, void *data)
4020{
4021 BT_DBG("conn %p", conn);
4022
4023 return l2cap_connect_rsp(conn, cmd, data);
4024}
4025
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004026static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004027 u16 icid, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004028{
4029 struct l2cap_move_chan_rsp rsp;
4030
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004031 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004032
4033 rsp.icid = cpu_to_le16(icid);
4034 rsp.result = cpu_to_le16(result);
4035
4036 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_RSP, sizeof(rsp), &rsp);
4037}
4038
4039static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004040 struct l2cap_chan *chan,
4041 u16 icid, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004042{
4043 struct l2cap_move_chan_cfm cfm;
4044 u8 ident;
4045
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004046 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004047
4048 ident = l2cap_get_ident(conn);
4049 if (chan)
4050 chan->ident = ident;
4051
4052 cfm.icid = cpu_to_le16(icid);
4053 cfm.result = cpu_to_le16(result);
4054
4055 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM, sizeof(cfm), &cfm);
4056}
4057
4058static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004059 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004060{
4061 struct l2cap_move_chan_cfm_rsp rsp;
4062
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004063 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004064
4065 rsp.icid = cpu_to_le16(icid);
4066 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4067}
4068
4069static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004070 struct l2cap_cmd_hdr *cmd,
4071 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004072{
4073 struct l2cap_move_chan_req *req = data;
4074 u16 icid = 0;
4075 u16 result = L2CAP_MR_NOT_ALLOWED;
4076
4077 if (cmd_len != sizeof(*req))
4078 return -EPROTO;
4079
4080 icid = le16_to_cpu(req->icid);
4081
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004082 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004083
4084 if (!enable_hs)
4085 return -EINVAL;
4086
4087 /* Placeholder: Always refuse */
4088 l2cap_send_move_chan_rsp(conn, cmd->ident, icid, result);
4089
4090 return 0;
4091}
4092
4093static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004094 struct l2cap_cmd_hdr *cmd,
4095 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004096{
4097 struct l2cap_move_chan_rsp *rsp = data;
4098 u16 icid, result;
4099
4100 if (cmd_len != sizeof(*rsp))
4101 return -EPROTO;
4102
4103 icid = le16_to_cpu(rsp->icid);
4104 result = le16_to_cpu(rsp->result);
4105
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004106 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004107
4108 /* Placeholder: Always unconfirmed */
4109 l2cap_send_move_chan_cfm(conn, NULL, icid, L2CAP_MC_UNCONFIRMED);
4110
4111 return 0;
4112}
4113
4114static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004115 struct l2cap_cmd_hdr *cmd,
4116 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004117{
4118 struct l2cap_move_chan_cfm *cfm = data;
4119 u16 icid, result;
4120
4121 if (cmd_len != sizeof(*cfm))
4122 return -EPROTO;
4123
4124 icid = le16_to_cpu(cfm->icid);
4125 result = le16_to_cpu(cfm->result);
4126
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004127 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004128
4129 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4130
4131 return 0;
4132}
4133
4134static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004135 struct l2cap_cmd_hdr *cmd,
4136 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004137{
4138 struct l2cap_move_chan_cfm_rsp *rsp = data;
4139 u16 icid;
4140
4141 if (cmd_len != sizeof(*rsp))
4142 return -EPROTO;
4143
4144 icid = le16_to_cpu(rsp->icid);
4145
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004146 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004147
4148 return 0;
4149}
4150
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004151static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Claudio Takahaside731152011-02-11 19:28:55 -02004152 u16 to_multiplier)
4153{
4154 u16 max_latency;
4155
4156 if (min > max || min < 6 || max > 3200)
4157 return -EINVAL;
4158
4159 if (to_multiplier < 10 || to_multiplier > 3200)
4160 return -EINVAL;
4161
4162 if (max >= to_multiplier * 8)
4163 return -EINVAL;
4164
4165 max_latency = (to_multiplier * 8 / max) - 1;
4166 if (latency > 499 || latency > max_latency)
4167 return -EINVAL;
4168
4169 return 0;
4170}
4171
4172static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
4173 struct l2cap_cmd_hdr *cmd, u8 *data)
4174{
4175 struct hci_conn *hcon = conn->hcon;
4176 struct l2cap_conn_param_update_req *req;
4177 struct l2cap_conn_param_update_rsp rsp;
4178 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004179 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02004180
4181 if (!(hcon->link_mode & HCI_LM_MASTER))
4182 return -EINVAL;
4183
4184 cmd_len = __le16_to_cpu(cmd->len);
4185 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
4186 return -EPROTO;
4187
4188 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004189 min = __le16_to_cpu(req->min);
4190 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02004191 latency = __le16_to_cpu(req->latency);
4192 to_multiplier = __le16_to_cpu(req->to_multiplier);
4193
4194 BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
4195 min, max, latency, to_multiplier);
4196
4197 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004198
4199 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
4200 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004201 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004202 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004203 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004204
4205 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
4206 sizeof(rsp), &rsp);
4207
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004208 if (!err)
4209 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
4210
Claudio Takahaside731152011-02-11 19:28:55 -02004211 return 0;
4212}
4213
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004214static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
4215 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
4216{
4217 int err = 0;
4218
4219 switch (cmd->code) {
4220 case L2CAP_COMMAND_REJ:
4221 l2cap_command_rej(conn, cmd, data);
4222 break;
4223
4224 case L2CAP_CONN_REQ:
4225 err = l2cap_connect_req(conn, cmd, data);
4226 break;
4227
4228 case L2CAP_CONN_RSP:
4229 err = l2cap_connect_rsp(conn, cmd, data);
4230 break;
4231
4232 case L2CAP_CONF_REQ:
4233 err = l2cap_config_req(conn, cmd, cmd_len, data);
4234 break;
4235
4236 case L2CAP_CONF_RSP:
4237 err = l2cap_config_rsp(conn, cmd, data);
4238 break;
4239
4240 case L2CAP_DISCONN_REQ:
4241 err = l2cap_disconnect_req(conn, cmd, data);
4242 break;
4243
4244 case L2CAP_DISCONN_RSP:
4245 err = l2cap_disconnect_rsp(conn, cmd, data);
4246 break;
4247
4248 case L2CAP_ECHO_REQ:
4249 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
4250 break;
4251
4252 case L2CAP_ECHO_RSP:
4253 break;
4254
4255 case L2CAP_INFO_REQ:
4256 err = l2cap_information_req(conn, cmd, data);
4257 break;
4258
4259 case L2CAP_INFO_RSP:
4260 err = l2cap_information_rsp(conn, cmd, data);
4261 break;
4262
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004263 case L2CAP_CREATE_CHAN_REQ:
4264 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
4265 break;
4266
4267 case L2CAP_CREATE_CHAN_RSP:
4268 err = l2cap_create_channel_rsp(conn, cmd, data);
4269 break;
4270
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004271 case L2CAP_MOVE_CHAN_REQ:
4272 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
4273 break;
4274
4275 case L2CAP_MOVE_CHAN_RSP:
4276 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
4277 break;
4278
4279 case L2CAP_MOVE_CHAN_CFM:
4280 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
4281 break;
4282
4283 case L2CAP_MOVE_CHAN_CFM_RSP:
4284 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
4285 break;
4286
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004287 default:
4288 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
4289 err = -EINVAL;
4290 break;
4291 }
4292
4293 return err;
4294}
4295
4296static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
4297 struct l2cap_cmd_hdr *cmd, u8 *data)
4298{
4299 switch (cmd->code) {
4300 case L2CAP_COMMAND_REJ:
4301 return 0;
4302
4303 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02004304 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004305
4306 case L2CAP_CONN_PARAM_UPDATE_RSP:
4307 return 0;
4308
4309 default:
4310 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
4311 return -EINVAL;
4312 }
4313}
4314
4315static inline void l2cap_sig_channel(struct l2cap_conn *conn,
4316 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004317{
4318 u8 *data = skb->data;
4319 int len = skb->len;
4320 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004321 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004322
4323 l2cap_raw_recv(conn, skb);
4324
4325 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07004326 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004327 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
4328 data += L2CAP_CMD_HDR_SIZE;
4329 len -= L2CAP_CMD_HDR_SIZE;
4330
Al Viro88219a02007-07-29 00:17:25 -07004331 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004332
Al Viro88219a02007-07-29 00:17:25 -07004333 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len, cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004334
Al Viro88219a02007-07-29 00:17:25 -07004335 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004336 BT_DBG("corrupted command");
4337 break;
4338 }
4339
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004340 if (conn->hcon->type == LE_LINK)
4341 err = l2cap_le_sig_cmd(conn, &cmd, data);
4342 else
4343 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004344
4345 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004346 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03004347
4348 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004349
4350 /* FIXME: Map err to a valid reason */
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004351 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004352 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
4353 }
4354
Al Viro88219a02007-07-29 00:17:25 -07004355 data += cmd_len;
4356 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004357 }
4358
4359 kfree_skb(skb);
4360}
4361
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004362static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004363{
4364 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03004365 int hdr_size;
4366
4367 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
4368 hdr_size = L2CAP_EXT_HDR_SIZE;
4369 else
4370 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004371
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004372 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004373 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004374 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
4375 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
4376
4377 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03004378 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004379 }
4380 return 0;
4381}
4382
Mat Martineau6ea00482012-05-17 20:53:52 -07004383static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004384{
Mat Martineaue31f7632012-05-17 20:53:41 -07004385 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004386
Mat Martineaue31f7632012-05-17 20:53:41 -07004387 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004388
Mat Martineaue31f7632012-05-17 20:53:41 -07004389 memset(&control, 0, sizeof(control));
4390 control.sframe = 1;
4391 control.final = 1;
4392 control.reqseq = chan->buffer_seq;
4393 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004394
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004395 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07004396 control.super = L2CAP_SUPER_RNR;
4397 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004398 }
4399
Mat Martineaue31f7632012-05-17 20:53:41 -07004400 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
4401 chan->unacked_frames > 0)
4402 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004403
Mat Martineaue31f7632012-05-17 20:53:41 -07004404 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03004405 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004406
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004407 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07004408 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
4409 /* F-bit wasn't sent in an s-frame or i-frame yet, so
4410 * send it now.
4411 */
4412 control.super = L2CAP_SUPER_RR;
4413 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004414 }
4415}
4416
Mat Martineau84084a32011-07-22 14:54:00 -07004417static void append_skb_frag(struct sk_buff *skb,
4418 struct sk_buff *new_frag, struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004419{
Mat Martineau84084a32011-07-22 14:54:00 -07004420 /* skb->len reflects data in skb as well as all fragments
4421 * skb->data_len reflects only data in fragments
4422 */
4423 if (!skb_has_frag_list(skb))
4424 skb_shinfo(skb)->frag_list = new_frag;
4425
4426 new_frag->next = NULL;
4427
4428 (*last_frag)->next = new_frag;
4429 *last_frag = new_frag;
4430
4431 skb->len += new_frag->len;
4432 skb->data_len += new_frag->len;
4433 skb->truesize += new_frag->truesize;
4434}
4435
Mat Martineau4b51dae92012-05-17 20:53:37 -07004436static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
4437 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07004438{
4439 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004440
Mat Martineau4b51dae92012-05-17 20:53:37 -07004441 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004442 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07004443 if (chan->sdu)
4444 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004445
Gustavo Padovan80b98022012-05-27 22:27:51 -03004446 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07004447 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004448
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004449 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07004450 if (chan->sdu)
4451 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004452
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004453 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004454 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004455
Mat Martineau84084a32011-07-22 14:54:00 -07004456 if (chan->sdu_len > chan->imtu) {
4457 err = -EMSGSIZE;
4458 break;
4459 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004460
Mat Martineau84084a32011-07-22 14:54:00 -07004461 if (skb->len >= chan->sdu_len)
4462 break;
4463
4464 chan->sdu = skb;
4465 chan->sdu_last_frag = skb;
4466
4467 skb = NULL;
4468 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004469 break;
4470
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004471 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004472 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004473 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004474
Mat Martineau84084a32011-07-22 14:54:00 -07004475 append_skb_frag(chan->sdu, skb,
4476 &chan->sdu_last_frag);
4477 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004478
Mat Martineau84084a32011-07-22 14:54:00 -07004479 if (chan->sdu->len >= chan->sdu_len)
4480 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004481
Mat Martineau84084a32011-07-22 14:54:00 -07004482 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004483 break;
4484
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004485 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004486 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004487 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004488
Mat Martineau84084a32011-07-22 14:54:00 -07004489 append_skb_frag(chan->sdu, skb,
4490 &chan->sdu_last_frag);
4491 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004492
Mat Martineau84084a32011-07-22 14:54:00 -07004493 if (chan->sdu->len != chan->sdu_len)
4494 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004495
Gustavo Padovan80b98022012-05-27 22:27:51 -03004496 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004497
Mat Martineau84084a32011-07-22 14:54:00 -07004498 if (!err) {
4499 /* Reassembly complete */
4500 chan->sdu = NULL;
4501 chan->sdu_last_frag = NULL;
4502 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004503 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004504 break;
4505 }
4506
Mat Martineau84084a32011-07-22 14:54:00 -07004507 if (err) {
4508 kfree_skb(skb);
4509 kfree_skb(chan->sdu);
4510 chan->sdu = NULL;
4511 chan->sdu_last_frag = NULL;
4512 chan->sdu_len = 0;
4513 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004514
Mat Martineau84084a32011-07-22 14:54:00 -07004515 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004516}
4517
Mat Martineaue3281402011-07-07 09:39:02 -07004518void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03004519{
Mat Martineau61aa4f52012-05-17 20:53:40 -07004520 u8 event;
4521
4522 if (chan->mode != L2CAP_MODE_ERTM)
4523 return;
4524
4525 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03004526 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004527}
4528
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004529static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
4530{
Mat Martineau63838722012-05-17 20:53:45 -07004531 int err = 0;
4532 /* Pass sequential frames to l2cap_reassemble_sdu()
4533 * until a gap is encountered.
4534 */
4535
4536 BT_DBG("chan %p", chan);
4537
4538 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4539 struct sk_buff *skb;
4540 BT_DBG("Searching for skb with txseq %d (queue len %d)",
4541 chan->buffer_seq, skb_queue_len(&chan->srej_q));
4542
4543 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
4544
4545 if (!skb)
4546 break;
4547
4548 skb_unlink(skb, &chan->srej_q);
4549 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
4550 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
4551 if (err)
4552 break;
4553 }
4554
4555 if (skb_queue_empty(&chan->srej_q)) {
4556 chan->rx_state = L2CAP_RX_STATE_RECV;
4557 l2cap_send_ack(chan);
4558 }
4559
4560 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004561}
4562
4563static void l2cap_handle_srej(struct l2cap_chan *chan,
4564 struct l2cap_ctrl *control)
4565{
Mat Martineauf80842a2012-05-17 20:53:46 -07004566 struct sk_buff *skb;
4567
4568 BT_DBG("chan %p, control %p", chan, control);
4569
4570 if (control->reqseq == chan->next_tx_seq) {
4571 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4572 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4573 return;
4574 }
4575
4576 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4577
4578 if (skb == NULL) {
4579 BT_DBG("Seq %d not available for retransmission",
4580 control->reqseq);
4581 return;
4582 }
4583
4584 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
4585 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4586 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4587 return;
4588 }
4589
4590 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4591
4592 if (control->poll) {
4593 l2cap_pass_to_tx(chan, control);
4594
4595 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4596 l2cap_retransmit(chan, control);
4597 l2cap_ertm_send(chan);
4598
4599 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4600 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4601 chan->srej_save_reqseq = control->reqseq;
4602 }
4603 } else {
4604 l2cap_pass_to_tx_fbit(chan, control);
4605
4606 if (control->final) {
4607 if (chan->srej_save_reqseq != control->reqseq ||
4608 !test_and_clear_bit(CONN_SREJ_ACT,
4609 &chan->conn_state))
4610 l2cap_retransmit(chan, control);
4611 } else {
4612 l2cap_retransmit(chan, control);
4613 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4614 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4615 chan->srej_save_reqseq = control->reqseq;
4616 }
4617 }
4618 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004619}
4620
4621static void l2cap_handle_rej(struct l2cap_chan *chan,
4622 struct l2cap_ctrl *control)
4623{
Mat Martineaufcd289d2012-05-17 20:53:47 -07004624 struct sk_buff *skb;
4625
4626 BT_DBG("chan %p, control %p", chan, control);
4627
4628 if (control->reqseq == chan->next_tx_seq) {
4629 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4630 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4631 return;
4632 }
4633
4634 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4635
4636 if (chan->max_tx && skb &&
4637 bt_cb(skb)->control.retries >= chan->max_tx) {
4638 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4639 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4640 return;
4641 }
4642
4643 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4644
4645 l2cap_pass_to_tx(chan, control);
4646
4647 if (control->final) {
4648 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
4649 l2cap_retransmit_all(chan, control);
4650 } else {
4651 l2cap_retransmit_all(chan, control);
4652 l2cap_ertm_send(chan);
4653 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
4654 set_bit(CONN_REJ_ACT, &chan->conn_state);
4655 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004656}
4657
Mat Martineau4b51dae92012-05-17 20:53:37 -07004658static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
4659{
4660 BT_DBG("chan %p, txseq %d", chan, txseq);
4661
4662 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
4663 chan->expected_tx_seq);
4664
4665 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
4666 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4667 chan->tx_win) {
4668 /* See notes below regarding "double poll" and
4669 * invalid packets.
4670 */
4671 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4672 BT_DBG("Invalid/Ignore - after SREJ");
4673 return L2CAP_TXSEQ_INVALID_IGNORE;
4674 } else {
4675 BT_DBG("Invalid - in window after SREJ sent");
4676 return L2CAP_TXSEQ_INVALID;
4677 }
4678 }
4679
4680 if (chan->srej_list.head == txseq) {
4681 BT_DBG("Expected SREJ");
4682 return L2CAP_TXSEQ_EXPECTED_SREJ;
4683 }
4684
4685 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
4686 BT_DBG("Duplicate SREJ - txseq already stored");
4687 return L2CAP_TXSEQ_DUPLICATE_SREJ;
4688 }
4689
4690 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
4691 BT_DBG("Unexpected SREJ - not requested");
4692 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
4693 }
4694 }
4695
4696 if (chan->expected_tx_seq == txseq) {
4697 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4698 chan->tx_win) {
4699 BT_DBG("Invalid - txseq outside tx window");
4700 return L2CAP_TXSEQ_INVALID;
4701 } else {
4702 BT_DBG("Expected");
4703 return L2CAP_TXSEQ_EXPECTED;
4704 }
4705 }
4706
4707 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
4708 __seq_offset(chan, chan->expected_tx_seq,
4709 chan->last_acked_seq)){
4710 BT_DBG("Duplicate - expected_tx_seq later than txseq");
4711 return L2CAP_TXSEQ_DUPLICATE;
4712 }
4713
4714 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
4715 /* A source of invalid packets is a "double poll" condition,
4716 * where delays cause us to send multiple poll packets. If
4717 * the remote stack receives and processes both polls,
4718 * sequence numbers can wrap around in such a way that a
4719 * resent frame has a sequence number that looks like new data
4720 * with a sequence gap. This would trigger an erroneous SREJ
4721 * request.
4722 *
4723 * Fortunately, this is impossible with a tx window that's
4724 * less than half of the maximum sequence number, which allows
4725 * invalid frames to be safely ignored.
4726 *
4727 * With tx window sizes greater than half of the tx window
4728 * maximum, the frame is invalid and cannot be ignored. This
4729 * causes a disconnect.
4730 */
4731
4732 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4733 BT_DBG("Invalid/Ignore - txseq outside tx window");
4734 return L2CAP_TXSEQ_INVALID_IGNORE;
4735 } else {
4736 BT_DBG("Invalid - txseq outside tx window");
4737 return L2CAP_TXSEQ_INVALID;
4738 }
4739 } else {
4740 BT_DBG("Unexpected - txseq indicates missing frames");
4741 return L2CAP_TXSEQ_UNEXPECTED;
4742 }
4743}
4744
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004745static int l2cap_rx_state_recv(struct l2cap_chan *chan,
4746 struct l2cap_ctrl *control,
4747 struct sk_buff *skb, u8 event)
4748{
4749 int err = 0;
4750 bool skb_in_use = 0;
4751
4752 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4753 event);
4754
4755 switch (event) {
4756 case L2CAP_EV_RECV_IFRAME:
4757 switch (l2cap_classify_txseq(chan, control->txseq)) {
4758 case L2CAP_TXSEQ_EXPECTED:
4759 l2cap_pass_to_tx(chan, control);
4760
4761 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4762 BT_DBG("Busy, discarding expected seq %d",
4763 control->txseq);
4764 break;
4765 }
4766
4767 chan->expected_tx_seq = __next_seq(chan,
4768 control->txseq);
4769
4770 chan->buffer_seq = chan->expected_tx_seq;
4771 skb_in_use = 1;
4772
4773 err = l2cap_reassemble_sdu(chan, skb, control);
4774 if (err)
4775 break;
4776
4777 if (control->final) {
4778 if (!test_and_clear_bit(CONN_REJ_ACT,
4779 &chan->conn_state)) {
4780 control->final = 0;
4781 l2cap_retransmit_all(chan, control);
4782 l2cap_ertm_send(chan);
4783 }
4784 }
4785
4786 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
4787 l2cap_send_ack(chan);
4788 break;
4789 case L2CAP_TXSEQ_UNEXPECTED:
4790 l2cap_pass_to_tx(chan, control);
4791
4792 /* Can't issue SREJ frames in the local busy state.
4793 * Drop this frame, it will be seen as missing
4794 * when local busy is exited.
4795 */
4796 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4797 BT_DBG("Busy, discarding unexpected seq %d",
4798 control->txseq);
4799 break;
4800 }
4801
4802 /* There was a gap in the sequence, so an SREJ
4803 * must be sent for each missing frame. The
4804 * current frame is stored for later use.
4805 */
4806 skb_queue_tail(&chan->srej_q, skb);
4807 skb_in_use = 1;
4808 BT_DBG("Queued %p (queue len %d)", skb,
4809 skb_queue_len(&chan->srej_q));
4810
4811 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
4812 l2cap_seq_list_clear(&chan->srej_list);
4813 l2cap_send_srej(chan, control->txseq);
4814
4815 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
4816 break;
4817 case L2CAP_TXSEQ_DUPLICATE:
4818 l2cap_pass_to_tx(chan, control);
4819 break;
4820 case L2CAP_TXSEQ_INVALID_IGNORE:
4821 break;
4822 case L2CAP_TXSEQ_INVALID:
4823 default:
4824 l2cap_send_disconn_req(chan->conn, chan,
4825 ECONNRESET);
4826 break;
4827 }
4828 break;
4829 case L2CAP_EV_RECV_RR:
4830 l2cap_pass_to_tx(chan, control);
4831 if (control->final) {
4832 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4833
4834 if (!test_and_clear_bit(CONN_REJ_ACT,
4835 &chan->conn_state)) {
4836 control->final = 0;
4837 l2cap_retransmit_all(chan, control);
4838 }
4839
4840 l2cap_ertm_send(chan);
4841 } else if (control->poll) {
4842 l2cap_send_i_or_rr_or_rnr(chan);
4843 } else {
4844 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4845 &chan->conn_state) &&
4846 chan->unacked_frames)
4847 __set_retrans_timer(chan);
4848
4849 l2cap_ertm_send(chan);
4850 }
4851 break;
4852 case L2CAP_EV_RECV_RNR:
4853 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4854 l2cap_pass_to_tx(chan, control);
4855 if (control && control->poll) {
4856 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4857 l2cap_send_rr_or_rnr(chan, 0);
4858 }
4859 __clear_retrans_timer(chan);
4860 l2cap_seq_list_clear(&chan->retrans_list);
4861 break;
4862 case L2CAP_EV_RECV_REJ:
4863 l2cap_handle_rej(chan, control);
4864 break;
4865 case L2CAP_EV_RECV_SREJ:
4866 l2cap_handle_srej(chan, control);
4867 break;
4868 default:
4869 break;
4870 }
4871
4872 if (skb && !skb_in_use) {
4873 BT_DBG("Freeing %p", skb);
4874 kfree_skb(skb);
4875 }
4876
4877 return err;
4878}
4879
4880static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
4881 struct l2cap_ctrl *control,
4882 struct sk_buff *skb, u8 event)
4883{
4884 int err = 0;
4885 u16 txseq = control->txseq;
4886 bool skb_in_use = 0;
4887
4888 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4889 event);
4890
4891 switch (event) {
4892 case L2CAP_EV_RECV_IFRAME:
4893 switch (l2cap_classify_txseq(chan, txseq)) {
4894 case L2CAP_TXSEQ_EXPECTED:
4895 /* Keep frame for reassembly later */
4896 l2cap_pass_to_tx(chan, control);
4897 skb_queue_tail(&chan->srej_q, skb);
4898 skb_in_use = 1;
4899 BT_DBG("Queued %p (queue len %d)", skb,
4900 skb_queue_len(&chan->srej_q));
4901
4902 chan->expected_tx_seq = __next_seq(chan, txseq);
4903 break;
4904 case L2CAP_TXSEQ_EXPECTED_SREJ:
4905 l2cap_seq_list_pop(&chan->srej_list);
4906
4907 l2cap_pass_to_tx(chan, control);
4908 skb_queue_tail(&chan->srej_q, skb);
4909 skb_in_use = 1;
4910 BT_DBG("Queued %p (queue len %d)", skb,
4911 skb_queue_len(&chan->srej_q));
4912
4913 err = l2cap_rx_queued_iframes(chan);
4914 if (err)
4915 break;
4916
4917 break;
4918 case L2CAP_TXSEQ_UNEXPECTED:
4919 /* Got a frame that can't be reassembled yet.
4920 * Save it for later, and send SREJs to cover
4921 * the missing frames.
4922 */
4923 skb_queue_tail(&chan->srej_q, skb);
4924 skb_in_use = 1;
4925 BT_DBG("Queued %p (queue len %d)", skb,
4926 skb_queue_len(&chan->srej_q));
4927
4928 l2cap_pass_to_tx(chan, control);
4929 l2cap_send_srej(chan, control->txseq);
4930 break;
4931 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
4932 /* This frame was requested with an SREJ, but
4933 * some expected retransmitted frames are
4934 * missing. Request retransmission of missing
4935 * SREJ'd frames.
4936 */
4937 skb_queue_tail(&chan->srej_q, skb);
4938 skb_in_use = 1;
4939 BT_DBG("Queued %p (queue len %d)", skb,
4940 skb_queue_len(&chan->srej_q));
4941
4942 l2cap_pass_to_tx(chan, control);
4943 l2cap_send_srej_list(chan, control->txseq);
4944 break;
4945 case L2CAP_TXSEQ_DUPLICATE_SREJ:
4946 /* We've already queued this frame. Drop this copy. */
4947 l2cap_pass_to_tx(chan, control);
4948 break;
4949 case L2CAP_TXSEQ_DUPLICATE:
4950 /* Expecting a later sequence number, so this frame
4951 * was already received. Ignore it completely.
4952 */
4953 break;
4954 case L2CAP_TXSEQ_INVALID_IGNORE:
4955 break;
4956 case L2CAP_TXSEQ_INVALID:
4957 default:
4958 l2cap_send_disconn_req(chan->conn, chan,
4959 ECONNRESET);
4960 break;
4961 }
4962 break;
4963 case L2CAP_EV_RECV_RR:
4964 l2cap_pass_to_tx(chan, control);
4965 if (control->final) {
4966 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4967
4968 if (!test_and_clear_bit(CONN_REJ_ACT,
4969 &chan->conn_state)) {
4970 control->final = 0;
4971 l2cap_retransmit_all(chan, control);
4972 }
4973
4974 l2cap_ertm_send(chan);
4975 } else if (control->poll) {
4976 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4977 &chan->conn_state) &&
4978 chan->unacked_frames) {
4979 __set_retrans_timer(chan);
4980 }
4981
4982 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4983 l2cap_send_srej_tail(chan);
4984 } else {
4985 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4986 &chan->conn_state) &&
4987 chan->unacked_frames)
4988 __set_retrans_timer(chan);
4989
4990 l2cap_send_ack(chan);
4991 }
4992 break;
4993 case L2CAP_EV_RECV_RNR:
4994 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4995 l2cap_pass_to_tx(chan, control);
4996 if (control->poll) {
4997 l2cap_send_srej_tail(chan);
4998 } else {
4999 struct l2cap_ctrl rr_control;
5000 memset(&rr_control, 0, sizeof(rr_control));
5001 rr_control.sframe = 1;
5002 rr_control.super = L2CAP_SUPER_RR;
5003 rr_control.reqseq = chan->buffer_seq;
5004 l2cap_send_sframe(chan, &rr_control);
5005 }
5006
5007 break;
5008 case L2CAP_EV_RECV_REJ:
5009 l2cap_handle_rej(chan, control);
5010 break;
5011 case L2CAP_EV_RECV_SREJ:
5012 l2cap_handle_srej(chan, control);
5013 break;
5014 }
5015
5016 if (skb && !skb_in_use) {
5017 BT_DBG("Freeing %p", skb);
5018 kfree_skb(skb);
5019 }
5020
5021 return err;
5022}
5023
5024static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
5025{
5026 /* Make sure reqseq is for a packet that has been sent but not acked */
5027 u16 unacked;
5028
5029 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
5030 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
5031}
5032
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005033static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5034 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005035{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005036 int err = 0;
5037
5038 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
5039 control, skb, event, chan->rx_state);
5040
5041 if (__valid_reqseq(chan, control->reqseq)) {
5042 switch (chan->rx_state) {
5043 case L2CAP_RX_STATE_RECV:
5044 err = l2cap_rx_state_recv(chan, control, skb, event);
5045 break;
5046 case L2CAP_RX_STATE_SREJ_SENT:
5047 err = l2cap_rx_state_srej_sent(chan, control, skb,
5048 event);
5049 break;
5050 default:
5051 /* shut it down */
5052 break;
5053 }
5054 } else {
5055 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
5056 control->reqseq, chan->next_tx_seq,
5057 chan->expected_ack_seq);
5058 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
5059 }
5060
5061 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005062}
5063
5064static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5065 struct sk_buff *skb)
5066{
Mat Martineau4b51dae92012-05-17 20:53:37 -07005067 int err = 0;
5068
5069 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
5070 chan->rx_state);
5071
5072 if (l2cap_classify_txseq(chan, control->txseq) ==
5073 L2CAP_TXSEQ_EXPECTED) {
5074 l2cap_pass_to_tx(chan, control);
5075
5076 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
5077 __next_seq(chan, chan->buffer_seq));
5078
5079 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5080
5081 l2cap_reassemble_sdu(chan, skb, control);
5082 } else {
5083 if (chan->sdu) {
5084 kfree_skb(chan->sdu);
5085 chan->sdu = NULL;
5086 }
5087 chan->sdu_last_frag = NULL;
5088 chan->sdu_len = 0;
5089
5090 if (skb) {
5091 BT_DBG("Freeing %p", skb);
5092 kfree_skb(skb);
5093 }
5094 }
5095
5096 chan->last_acked_seq = control->txseq;
5097 chan->expected_tx_seq = __next_seq(chan, control->txseq);
5098
5099 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005100}
5101
5102static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
5103{
5104 struct l2cap_ctrl *control = &bt_cb(skb)->control;
5105 u16 len;
5106 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005107
Mat Martineaub76bbd62012-04-11 10:48:43 -07005108 __unpack_control(chan, skb);
5109
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005110 len = skb->len;
5111
5112 /*
5113 * We can just drop the corrupted I-frame here.
5114 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005115 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005116 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005117 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005118 goto drop;
5119
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005120 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005121 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005122
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005123 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005124 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005125
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005126 if (len > chan->mps) {
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005127 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005128 goto drop;
5129 }
5130
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005131 if (!control->sframe) {
5132 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005133
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005134 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
5135 control->sar, control->reqseq, control->final,
5136 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03005137
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005138 /* Validate F-bit - F=0 always valid, F=1 only
5139 * valid in TX WAIT_F
5140 */
5141 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005142 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005143
5144 if (chan->mode != L2CAP_MODE_STREAMING) {
5145 event = L2CAP_EV_RECV_IFRAME;
5146 err = l2cap_rx(chan, control, skb, event);
5147 } else {
5148 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005149 }
5150
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005151 if (err)
5152 l2cap_send_disconn_req(chan->conn, chan,
5153 ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005154 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005155 const u8 rx_func_to_event[4] = {
5156 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
5157 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
5158 };
5159
5160 /* Only I-frames are expected in streaming mode */
5161 if (chan->mode == L2CAP_MODE_STREAMING)
5162 goto drop;
5163
5164 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
5165 control->reqseq, control->final, control->poll,
5166 control->super);
5167
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005168 if (len != 0) {
5169 BT_ERR("%d", len);
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005170 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005171 goto drop;
5172 }
5173
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005174 /* Validate F and P bits */
5175 if (control->final && (control->poll ||
5176 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
5177 goto drop;
5178
5179 event = rx_func_to_event[control->super];
5180 if (l2cap_rx(chan, control, skb, event))
5181 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005182 }
5183
5184 return 0;
5185
5186drop:
5187 kfree_skb(skb);
5188 return 0;
5189}
5190
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005191static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
5192 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005193{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005194 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005195
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03005196 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005197 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005198 if (cid == L2CAP_CID_A2MP) {
5199 chan = a2mp_channel_create(conn, skb);
5200 if (!chan) {
5201 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005202 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005203 }
5204
5205 l2cap_chan_lock(chan);
5206 } else {
5207 BT_DBG("unknown cid 0x%4.4x", cid);
5208 /* Drop packet and return */
5209 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005210 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005211 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005212 }
5213
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03005214 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005215
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005216 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005217 goto drop;
5218
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005219 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005220 case L2CAP_MODE_BASIC:
5221 /* If socket recv buffers overflows we drop data here
5222 * which is *bad* because L2CAP has to be reliable.
5223 * But we don't have any other choice. L2CAP doesn't
5224 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005225
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005226 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005227 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005228
Gustavo Padovan80b98022012-05-27 22:27:51 -03005229 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005230 goto done;
5231 break;
5232
5233 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005234 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005235 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005236 goto done;
5237
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005238 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005239 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005240 break;
5241 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005242
5243drop:
5244 kfree_skb(skb);
5245
5246done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005247 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005248}
5249
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03005250static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
5251 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005252{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005253 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005254
Ido Yarivc2287682012-04-20 15:46:07 -03005255 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005256 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005257 goto drop;
5258
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005259 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005260
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005261 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005262 goto drop;
5263
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005264 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005265 goto drop;
5266
Gustavo Padovan80b98022012-05-27 22:27:51 -03005267 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03005268 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005269
5270drop:
5271 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005272}
5273
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03005274static void l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
5275 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005276{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005277 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005278
Ido Yarivc2287682012-04-20 15:46:07 -03005279 chan = l2cap_global_chan_by_scid(0, cid, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005280 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005281 goto drop;
5282
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005283 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005284
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005285 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005286 goto drop;
5287
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005288 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005289 goto drop;
5290
Gustavo Padovan80b98022012-05-27 22:27:51 -03005291 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03005292 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005293
5294drop:
5295 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005296}
5297
Linus Torvalds1da177e2005-04-16 15:20:36 -07005298static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
5299{
5300 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07005301 u16 cid, len;
5302 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005303
5304 skb_pull(skb, L2CAP_HDR_SIZE);
5305 cid = __le16_to_cpu(lh->cid);
5306 len = __le16_to_cpu(lh->len);
5307
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005308 if (len != skb->len) {
5309 kfree_skb(skb);
5310 return;
5311 }
5312
Linus Torvalds1da177e2005-04-16 15:20:36 -07005313 BT_DBG("len %d, cid 0x%4.4x", len, cid);
5314
5315 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005316 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005317 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005318 l2cap_sig_channel(conn, skb);
5319 break;
5320
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005321 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02005322 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03005323 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005324 l2cap_conless_channel(conn, psm, skb);
5325 break;
5326
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005327 case L2CAP_CID_LE_DATA:
5328 l2cap_att_channel(conn, cid, skb);
5329 break;
5330
Anderson Brigliab501d6a2011-06-07 18:46:31 -03005331 case L2CAP_CID_SMP:
5332 if (smp_sig_channel(conn, skb))
5333 l2cap_conn_del(conn->hcon, EACCES);
5334 break;
5335
Linus Torvalds1da177e2005-04-16 15:20:36 -07005336 default:
5337 l2cap_data_channel(conn, cid, skb);
5338 break;
5339 }
5340}
5341
5342/* ---- L2CAP interface with lower layer (HCI) ---- */
5343
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005344int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005345{
5346 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005347 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005348
Linus Torvalds1da177e2005-04-16 15:20:36 -07005349 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
5350
5351 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005352 read_lock(&chan_list_lock);
5353 list_for_each_entry(c, &chan_list, global_l) {
5354 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005355
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005356 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005357 continue;
5358
5359 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005360 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005361 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005362 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005363 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005364 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
5365 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005366 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005367 lm2 |= HCI_LM_MASTER;
5368 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005369 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005370 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005371
5372 return exact ? lm1 : lm2;
5373}
5374
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03005375void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005376{
Marcel Holtmann01394182006-07-03 10:02:46 +02005377 struct l2cap_conn *conn;
5378
Linus Torvalds1da177e2005-04-16 15:20:36 -07005379 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
5380
Linus Torvalds1da177e2005-04-16 15:20:36 -07005381 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005382 conn = l2cap_conn_add(hcon, status);
5383 if (conn)
5384 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02005385 } else
Joe Perchese1750722011-06-29 18:18:29 -07005386 l2cap_conn_del(hcon, bt_to_errno(status));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005387
Linus Torvalds1da177e2005-04-16 15:20:36 -07005388}
5389
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005390int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01005391{
5392 struct l2cap_conn *conn = hcon->l2cap_data;
5393
5394 BT_DBG("hcon %p", hcon);
5395
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005396 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02005397 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01005398 return conn->disc_reason;
5399}
5400
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03005401void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005402{
5403 BT_DBG("hcon %p reason %d", hcon, reason);
5404
Joe Perchese1750722011-06-29 18:18:29 -07005405 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005406}
5407
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005408static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005409{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03005410 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01005411 return;
5412
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005413 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005414 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005415 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005416 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03005417 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005418 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005419 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03005420 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005421 }
5422}
5423
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005424int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005425{
Marcel Holtmann40be4922008-07-14 20:13:50 +02005426 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005427 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005428
Marcel Holtmann01394182006-07-03 10:02:46 +02005429 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005430 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02005431
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03005432 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005433
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005434 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05305435 if (!status && encrypt)
5436 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02005437 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005438 }
5439
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005440 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005441
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005442 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005443 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005444
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03005445 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
5446 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005447
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03005448 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
5449 l2cap_chan_unlock(chan);
5450 continue;
5451 }
5452
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005453 if (chan->scid == L2CAP_CID_LE_DATA) {
5454 if (!status && encrypt) {
5455 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02005456 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005457 }
5458
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005459 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005460 continue;
5461 }
5462
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03005463 if (test_bit(CONF_CONNECT_PEND, &chan->conf_state)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005464 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01005465 continue;
5466 }
5467
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005468 if (!status && (chan->state == BT_CONNECTED ||
5469 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03005470 struct sock *sk = chan->sk;
5471
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005472 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03005473 sk->sk_state_change(sk);
5474
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005475 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005476 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02005477 continue;
5478 }
5479
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005480 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005481 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03005482 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005483 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005484 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005485 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005486 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005487 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005488 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005489 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005490
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005491 lock_sock(sk);
5492
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005493 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005494 if (test_bit(BT_SK_DEFER_SETUP,
5495 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005496 struct sock *parent = bt_sk(sk)->parent;
5497 res = L2CAP_CR_PEND;
5498 stat = L2CAP_CS_AUTHOR_PEND;
Ilia Kolomisnky05e9a2f2011-07-15 18:30:21 +00005499 if (parent)
5500 parent->sk_data_ready(parent, 0);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005501 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005502 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005503 res = L2CAP_CR_SUCCESS;
5504 stat = L2CAP_CS_NO_INFO;
5505 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005506 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005507 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005508 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005509 res = L2CAP_CR_SEC_BLOCK;
5510 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005511 }
5512
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005513 release_sock(sk);
5514
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03005515 rsp.scid = cpu_to_le16(chan->dcid);
5516 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005517 rsp.result = cpu_to_le16(res);
5518 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03005519 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
5520 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07005521
5522 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
5523 res == L2CAP_CR_SUCCESS) {
5524 char buf[128];
5525 set_bit(CONF_REQ_SENT, &chan->conf_state);
5526 l2cap_send_cmd(conn, l2cap_get_ident(conn),
5527 L2CAP_CONF_REQ,
5528 l2cap_build_conf_req(chan, buf),
5529 buf);
5530 chan->num_conf_req++;
5531 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005532 }
5533
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005534 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005535 }
5536
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005537 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005538
Linus Torvalds1da177e2005-04-16 15:20:36 -07005539 return 0;
5540}
5541
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005542int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005543{
5544 struct l2cap_conn *conn = hcon->l2cap_data;
5545
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02005546 if (!conn)
5547 conn = l2cap_conn_add(hcon, 0);
5548
5549 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005550 goto drop;
5551
5552 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
5553
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +02005554 if (!(flags & ACL_CONT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005555 struct l2cap_hdr *hdr;
5556 int len;
5557
5558 if (conn->rx_len) {
5559 BT_ERR("Unexpected start frame (len %d)", skb->len);
5560 kfree_skb(conn->rx_skb);
5561 conn->rx_skb = NULL;
5562 conn->rx_len = 0;
5563 l2cap_conn_unreliable(conn, ECOMM);
5564 }
5565
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03005566 /* Start fragment always begin with Basic L2CAP header */
5567 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005568 BT_ERR("Frame is too short (len %d)", skb->len);
5569 l2cap_conn_unreliable(conn, ECOMM);
5570 goto drop;
5571 }
5572
5573 hdr = (struct l2cap_hdr *) skb->data;
5574 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
5575
5576 if (len == skb->len) {
5577 /* Complete frame received */
5578 l2cap_recv_frame(conn, skb);
5579 return 0;
5580 }
5581
5582 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
5583
5584 if (skb->len > len) {
5585 BT_ERR("Frame is too long (len %d, expected len %d)",
5586 skb->len, len);
5587 l2cap_conn_unreliable(conn, ECOMM);
5588 goto drop;
5589 }
5590
5591 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03005592 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
5593 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005594 goto drop;
5595
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005596 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01005597 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005598 conn->rx_len = len - skb->len;
5599 } else {
5600 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
5601
5602 if (!conn->rx_len) {
5603 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
5604 l2cap_conn_unreliable(conn, ECOMM);
5605 goto drop;
5606 }
5607
5608 if (skb->len > conn->rx_len) {
5609 BT_ERR("Fragment is too long (len %d, expected %d)",
5610 skb->len, conn->rx_len);
5611 kfree_skb(conn->rx_skb);
5612 conn->rx_skb = NULL;
5613 conn->rx_len = 0;
5614 l2cap_conn_unreliable(conn, ECOMM);
5615 goto drop;
5616 }
5617
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005618 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01005619 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005620 conn->rx_len -= skb->len;
5621
5622 if (!conn->rx_len) {
5623 /* Complete frame received */
5624 l2cap_recv_frame(conn, conn->rx_skb);
5625 conn->rx_skb = NULL;
5626 }
5627 }
5628
5629drop:
5630 kfree_skb(skb);
5631 return 0;
5632}
5633
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005634static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005635{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005636 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005637
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005638 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005639
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005640 list_for_each_entry(c, &chan_list, global_l) {
5641 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005642
Gustavo F. Padovan903d3432011-02-10 14:16:06 -02005643 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005644 batostr(&bt_sk(sk)->src),
5645 batostr(&bt_sk(sk)->dst),
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005646 c->state, __le16_to_cpu(c->psm),
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005647 c->scid, c->dcid, c->imtu, c->omtu,
5648 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02005649 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005650
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005651 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005652
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005653 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005654}
5655
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005656static int l2cap_debugfs_open(struct inode *inode, struct file *file)
5657{
5658 return single_open(file, l2cap_debugfs_show, inode->i_private);
5659}
5660
5661static const struct file_operations l2cap_debugfs_fops = {
5662 .open = l2cap_debugfs_open,
5663 .read = seq_read,
5664 .llseek = seq_lseek,
5665 .release = single_release,
5666};
5667
5668static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005669
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005670int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005671{
5672 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005673
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005674 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005675 if (err < 0)
5676 return err;
5677
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005678 if (bt_debugfs) {
5679 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
5680 bt_debugfs, NULL, &l2cap_debugfs_fops);
5681 if (!l2cap_debugfs)
5682 BT_ERR("Failed to create L2CAP debug file");
5683 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005684
Linus Torvalds1da177e2005-04-16 15:20:36 -07005685 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005686}
5687
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005688void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005689{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005690 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005691 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005692}
5693
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03005694module_param(disable_ertm, bool, 0644);
5695MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");