blob: daa149b7003cdd659120e79225a50c6216a6dce4 [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
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300409 atomic_set(&chan->refcnt, 1);
410
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
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300419void l2cap_chan_destroy(struct l2cap_chan *chan)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300420{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200421 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300422 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200423 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300424
Ulisses Furquim371fd832011-12-21 20:02:36 -0200425 l2cap_chan_put(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300426}
427
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300428void l2cap_chan_set_defaults(struct l2cap_chan *chan)
429{
430 chan->fcs = L2CAP_FCS_CRC16;
431 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
432 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
433 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700434 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300435 chan->sec_level = BT_SECURITY_LOW;
436
437 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
438}
439
Andrei Emeltchenko14a28492012-03-23 16:31:49 +0200440static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200441{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300442 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200443 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200444
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200445 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100446
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300447 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200448
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200449 switch (chan->chan_type) {
450 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300451 if (conn->hcon->type == LE_LINK) {
452 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300453 chan->omtu = L2CAP_DEFAULT_MTU;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300454 chan->scid = L2CAP_CID_LE_DATA;
455 chan->dcid = L2CAP_CID_LE_DATA;
Ville Tervob62f3282011-02-10 22:38:50 -0300456 } else {
457 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300458 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300459 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300460 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200461 break;
462
463 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200464 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300465 chan->scid = L2CAP_CID_CONN_LESS;
466 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300467 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200468 break;
469
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300470 case L2CAP_CHAN_CONN_FIX_A2MP:
471 chan->scid = L2CAP_CID_A2MP;
472 chan->dcid = L2CAP_CID_A2MP;
473 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
474 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
475 break;
476
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200477 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200478 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300479 chan->scid = L2CAP_CID_SIGNALING;
480 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300481 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200482 }
483
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300484 chan->local_id = L2CAP_BESTEFFORT_ID;
485 chan->local_stype = L2CAP_SERV_BESTEFFORT;
486 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
487 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
488 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
489 chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO;
490
Ulisses Furquim371fd832011-12-21 20:02:36 -0200491 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300492
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200493 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200494}
495
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300496void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200497{
498 mutex_lock(&conn->chan_lock);
499 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200500 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200501}
502
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300503void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200504{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300505 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200506
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300507 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200508
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300509 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200510
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900511 if (conn) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300512 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200513 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200514
Ulisses Furquim371fd832011-12-21 20:02:36 -0200515 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300516
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300517 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300518
519 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
520 hci_conn_put(conn->hcon);
Marcel Holtmann01394182006-07-03 10:02:46 +0200521 }
522
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300523 if (chan->ops->teardown)
524 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200525
Mat Martineau28270112012-05-17 21:14:09 -0700526 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300527 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300528
Gustavo Padovanee556f62012-05-18 20:22:38 -0300529 switch(chan->mode) {
530 case L2CAP_MODE_BASIC:
531 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300532
Gustavo Padovanee556f62012-05-18 20:22:38 -0300533 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300534 __clear_retrans_timer(chan);
535 __clear_monitor_timer(chan);
536 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300537
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300538 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300539
Mat Martineau3c588192012-04-11 10:48:42 -0700540 l2cap_seq_list_free(&chan->srej_list);
541 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300542
543 /* fall through */
544
545 case L2CAP_MODE_STREAMING:
546 skb_queue_purge(&chan->tx_q);
547 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300548 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300549
550 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200551}
552
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300553void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300554{
555 struct l2cap_conn *conn = chan->conn;
556 struct sock *sk = chan->sk;
557
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200558 BT_DBG("chan %p state %s sk %p", chan,
559 state_to_string(chan->state), sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300560
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300561 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300562 case BT_LISTEN:
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300563 if (chan->ops->teardown)
564 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300565 break;
566
567 case BT_CONNECTED:
568 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300569 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300570 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300571 __set_chan_timer(chan, sk->sk_sndtimeo);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300572 l2cap_send_disconn_req(conn, chan, reason);
573 } else
574 l2cap_chan_del(chan, reason);
575 break;
576
577 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300578 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300579 conn->hcon->type == ACL_LINK) {
580 struct l2cap_conn_rsp rsp;
581 __u16 result;
582
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300583 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300584 result = L2CAP_CR_SEC_BLOCK;
585 else
586 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300587 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300588
589 rsp.scid = cpu_to_le16(chan->dcid);
590 rsp.dcid = cpu_to_le16(chan->scid);
591 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300592 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300593 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
594 sizeof(rsp), &rsp);
595 }
596
597 l2cap_chan_del(chan, reason);
598 break;
599
600 case BT_CONNECT:
601 case BT_DISCONN:
602 l2cap_chan_del(chan, reason);
603 break;
604
605 default:
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300606 if (chan->ops->teardown)
607 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300608 break;
609 }
610}
611
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300612static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530613{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300614 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300615 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530616 case BT_SECURITY_HIGH:
617 return HCI_AT_DEDICATED_BONDING_MITM;
618 case BT_SECURITY_MEDIUM:
619 return HCI_AT_DEDICATED_BONDING;
620 default:
621 return HCI_AT_NO_BONDING;
622 }
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +0300623 } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300624 if (chan->sec_level == BT_SECURITY_LOW)
625 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530626
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300627 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530628 return HCI_AT_NO_BONDING_MITM;
629 else
630 return HCI_AT_NO_BONDING;
631 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300632 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530633 case BT_SECURITY_HIGH:
634 return HCI_AT_GENERAL_BONDING_MITM;
635 case BT_SECURITY_MEDIUM:
636 return HCI_AT_GENERAL_BONDING;
637 default:
638 return HCI_AT_NO_BONDING;
639 }
640 }
641}
642
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200643/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200644int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200645{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300646 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100647 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200648
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300649 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100650
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300651 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200652}
653
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200654static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200655{
656 u8 id;
657
658 /* Get next available identificator.
659 * 1 - 128 are used by kernel.
660 * 129 - 199 are reserved.
661 * 200 - 254 are used by utilities like l2ping, etc.
662 */
663
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200664 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200665
666 if (++conn->tx_ident > 128)
667 conn->tx_ident = 1;
668
669 id = conn->tx_ident;
670
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200671 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200672
673 return id;
674}
675
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300676static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200677{
678 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200679 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200680
681 BT_DBG("code 0x%2.2x", code);
682
683 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300684 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200685
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200686 if (lmp_no_flush_capable(conn->hcon->hdev))
687 flags = ACL_START_NO_FLUSH;
688 else
689 flags = ACL_START;
690
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700691 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200692 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700693
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200694 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200695}
696
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200697static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
698{
699 struct hci_conn *hcon = chan->conn->hcon;
700 u16 flags;
701
702 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
703 skb->priority);
704
705 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
706 lmp_no_flush_capable(hcon->hdev))
707 flags = ACL_START_NO_FLUSH;
708 else
709 flags = ACL_START;
710
711 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
712 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713}
714
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700715static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
716{
717 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
718 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
719
720 if (enh & L2CAP_CTRL_FRAME_TYPE) {
721 /* S-Frame */
722 control->sframe = 1;
723 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
724 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
725
726 control->sar = 0;
727 control->txseq = 0;
728 } else {
729 /* I-Frame */
730 control->sframe = 0;
731 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
732 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
733
734 control->poll = 0;
735 control->super = 0;
736 }
737}
738
739static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
740{
741 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
742 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
743
744 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
745 /* S-Frame */
746 control->sframe = 1;
747 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
748 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
749
750 control->sar = 0;
751 control->txseq = 0;
752 } else {
753 /* I-Frame */
754 control->sframe = 0;
755 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
756 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
757
758 control->poll = 0;
759 control->super = 0;
760 }
761}
762
763static inline void __unpack_control(struct l2cap_chan *chan,
764 struct sk_buff *skb)
765{
766 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
767 __unpack_extended_control(get_unaligned_le32(skb->data),
768 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700769 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700770 } else {
771 __unpack_enhanced_control(get_unaligned_le16(skb->data),
772 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700773 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700774 }
775}
776
777static u32 __pack_extended_control(struct l2cap_ctrl *control)
778{
779 u32 packed;
780
781 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
782 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
783
784 if (control->sframe) {
785 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
786 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
787 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
788 } else {
789 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
790 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
791 }
792
793 return packed;
794}
795
796static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
797{
798 u16 packed;
799
800 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
801 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
802
803 if (control->sframe) {
804 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
805 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
806 packed |= L2CAP_CTRL_FRAME_TYPE;
807 } else {
808 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
809 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
810 }
811
812 return packed;
813}
814
815static inline void __pack_control(struct l2cap_chan *chan,
816 struct l2cap_ctrl *control,
817 struct sk_buff *skb)
818{
819 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
820 put_unaligned_le32(__pack_extended_control(control),
821 skb->data + L2CAP_HDR_SIZE);
822 } else {
823 put_unaligned_le16(__pack_enhanced_control(control),
824 skb->data + L2CAP_HDR_SIZE);
825 }
826}
827
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300828static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
829{
830 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
831 return L2CAP_EXT_HDR_SIZE;
832 else
833 return L2CAP_ENH_HDR_SIZE;
834}
835
Mat Martineaua67d7f62012-05-17 20:53:35 -0700836static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
837 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300838{
839 struct sk_buff *skb;
840 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300841 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300842
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300843 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300844 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300845
Mat Martineaua67d7f62012-05-17 20:53:35 -0700846 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300847
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300848 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700849 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300850
851 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300852 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300853 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300854
Mat Martineaua67d7f62012-05-17 20:53:35 -0700855 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
856 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
857 else
858 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300859
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300860 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700861 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300862 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300863 }
864
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200865 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700866 return skb;
867}
868
869static void l2cap_send_sframe(struct l2cap_chan *chan,
870 struct l2cap_ctrl *control)
871{
872 struct sk_buff *skb;
873 u32 control_field;
874
875 BT_DBG("chan %p, control %p", chan, control);
876
877 if (!control->sframe)
878 return;
879
880 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
881 !control->poll)
882 control->final = 1;
883
884 if (control->super == L2CAP_SUPER_RR)
885 clear_bit(CONN_RNR_SENT, &chan->conn_state);
886 else if (control->super == L2CAP_SUPER_RNR)
887 set_bit(CONN_RNR_SENT, &chan->conn_state);
888
889 if (control->super != L2CAP_SUPER_SREJ) {
890 chan->last_acked_seq = control->reqseq;
891 __clear_ack_timer(chan);
892 }
893
894 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
895 control->final, control->poll, control->super);
896
897 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
898 control_field = __pack_extended_control(control);
899 else
900 control_field = __pack_enhanced_control(control);
901
902 skb = l2cap_create_sframe_pdu(chan, control_field);
903 if (!IS_ERR(skb))
904 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300905}
906
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700907static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300908{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700909 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300910
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700911 BT_DBG("chan %p, poll %d", chan, poll);
912
913 memset(&control, 0, sizeof(control));
914 control.sframe = 1;
915 control.poll = poll;
916
917 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
918 control.super = L2CAP_SUPER_RNR;
919 else
920 control.super = L2CAP_SUPER_RR;
921
922 control.reqseq = chan->buffer_seq;
923 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300924}
925
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300926static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300927{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -0300928 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300929}
930
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +0200931static void l2cap_send_conn_req(struct l2cap_chan *chan)
932{
933 struct l2cap_conn *conn = chan->conn;
934 struct l2cap_conn_req req;
935
936 req.scid = cpu_to_le16(chan->scid);
937 req.psm = chan->psm;
938
939 chan->ident = l2cap_get_ident(conn);
940
941 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
942
943 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
944}
945
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300946static void l2cap_chan_ready(struct l2cap_chan *chan)
947{
Mat Martineau28270112012-05-17 21:14:09 -0700948 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300949 chan->conf_state = 0;
950 __clear_chan_timer(chan);
951
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -0300952 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300953
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +0300954 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300955}
956
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -0300957static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200958{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300959 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200960
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300961 if (conn->hcon->type == LE_LINK) {
962 l2cap_chan_ready(chan);
963 return;
964 }
965
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200966 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100967 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
968 return;
969
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200970 if (l2cap_chan_check_security(chan) &&
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +0200971 __l2cap_no_conn_pending(chan))
972 l2cap_send_conn_req(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200973 } else {
974 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300975 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200976
977 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
978 conn->info_ident = l2cap_get_ident(conn);
979
Marcel Holtmannba13ccd2012-03-01 14:25:33 -0800980 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200981
982 l2cap_send_cmd(conn, conn->info_ident,
983 L2CAP_INFO_REQ, sizeof(req), &req);
984 }
985}
986
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300987static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
988{
989 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -0300990 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300991 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
992
993 switch (mode) {
994 case L2CAP_MODE_ERTM:
995 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
996 case L2CAP_MODE_STREAMING:
997 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
998 default:
999 return 0x00;
1000 }
1001}
1002
Gustavo F. Padovan4519de92011-04-28 17:55:53 -03001003static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001004{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001005 struct sock *sk = chan->sk;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001006 struct l2cap_disconn_req req;
1007
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001008 if (!conn)
1009 return;
1010
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001011 if (chan->mode == L2CAP_MODE_ERTM) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001012 __clear_retrans_timer(chan);
1013 __clear_monitor_timer(chan);
1014 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001015 }
1016
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001017 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1018 __l2cap_state_change(chan, BT_DISCONN);
1019 return;
1020 }
1021
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001022 req.dcid = cpu_to_le16(chan->dcid);
1023 req.scid = cpu_to_le16(chan->scid);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001024 l2cap_send_cmd(conn, l2cap_get_ident(conn),
1025 L2CAP_DISCONN_REQ, sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001026
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001027 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001028 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001029 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001030 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001031}
1032
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001034static void l2cap_conn_start(struct l2cap_conn *conn)
1035{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001036 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001037
1038 BT_DBG("conn %p", conn);
1039
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001040 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001041
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001042 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001043 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001044
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001045 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001046
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001047 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001048 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001049 continue;
1050 }
1051
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001052 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001053 if (!l2cap_chan_check_security(chan) ||
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001054 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001055 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001056 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001057 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001058
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001059 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
1060 && test_bit(CONF_STATE2_DEVICE,
1061 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001062 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001063 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001064 continue;
1065 }
1066
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001067 l2cap_send_conn_req(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001068
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001069 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001070 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001071 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001072 rsp.scid = cpu_to_le16(chan->dcid);
1073 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001074
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001075 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001076 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001077 if (test_bit(BT_SK_DEFER_SETUP,
1078 &bt_sk(sk)->flags)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001079 struct sock *parent = bt_sk(sk)->parent;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001080 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1081 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Ilia Kolomisnky05e9a2f2011-07-15 18:30:21 +00001082 if (parent)
1083 parent->sk_data_ready(parent, 0);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001084
1085 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001086 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001087 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1088 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001089 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001090 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001091 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001092 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1093 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001094 }
1095
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001096 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
1097 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001098
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001099 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001100 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001101 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001102 continue;
1103 }
1104
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001105 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001106 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001107 l2cap_build_conf_req(chan, buf), buf);
1108 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001109 }
1110
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001111 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001112 }
1113
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001114 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001115}
1116
Ido Yarivc2287682012-04-20 15:46:07 -03001117/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001118 * Returns closest match, locked.
1119 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001120static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001121 bdaddr_t *src,
1122 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001123{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001124 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001125
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001126 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001127
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001128 list_for_each_entry(c, &chan_list, global_l) {
1129 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001130
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001131 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001132 continue;
1133
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001134 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001135 int src_match, dst_match;
1136 int src_any, dst_any;
1137
Ville Tervob62f3282011-02-10 22:38:50 -03001138 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001139 src_match = !bacmp(&bt_sk(sk)->src, src);
1140 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1141 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001142 read_unlock(&chan_list_lock);
1143 return c;
1144 }
Ville Tervob62f3282011-02-10 22:38:50 -03001145
1146 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001147 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1148 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1149 if ((src_match && dst_any) || (src_any && dst_match) ||
1150 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001151 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001152 }
1153 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001154
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001155 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001156
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001157 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001158}
1159
1160static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1161{
Gustavo F. Padovanc916fbe2011-04-04 16:00:55 -03001162 struct sock *parent, *sk;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001163 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001164
1165 BT_DBG("");
1166
1167 /* Check if we have socket listening on cid */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001168 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
Ido Yarivc2287682012-04-20 15:46:07 -03001169 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001170 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001171 return;
1172
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001173 parent = pchan->sk;
1174
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001175 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001176
Gustavo Padovan80b98022012-05-27 22:27:51 -03001177 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001178 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001179 goto clean;
1180
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001181 sk = chan->sk;
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001182
Ville Tervob62f3282011-02-10 22:38:50 -03001183 hci_conn_hold(conn->hcon);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001184 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
Ville Tervob62f3282011-02-10 22:38:50 -03001185
Ville Tervob62f3282011-02-10 22:38:50 -03001186 bacpy(&bt_sk(sk)->src, conn->src);
1187 bacpy(&bt_sk(sk)->dst, conn->dst);
1188
Gustavo F. Padovand1010242011-03-25 00:39:48 -03001189 bt_accept_enqueue(parent, sk);
1190
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001191 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001192
Gustavo Padovan6754e0d2012-05-25 09:30:56 -03001193 l2cap_chan_ready(chan);
Ville Tervob62f3282011-02-10 22:38:50 -03001194
Ville Tervob62f3282011-02-10 22:38:50 -03001195clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001196 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001197}
1198
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001199static void l2cap_conn_ready(struct l2cap_conn *conn)
1200{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001201 struct l2cap_chan *chan;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001202
1203 BT_DBG("conn %p", conn);
1204
Ville Tervob62f3282011-02-10 22:38:50 -03001205 if (!conn->hcon->out && conn->hcon->type == LE_LINK)
1206 l2cap_le_conn_ready(conn);
1207
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001208 if (conn->hcon->out && conn->hcon->type == LE_LINK)
1209 smp_conn_security(conn, conn->hcon->pending_sec_level);
1210
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001211 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001212
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001213 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001214
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001215 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001216
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001217 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1218 l2cap_chan_unlock(chan);
1219 continue;
1220 }
1221
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001222 if (conn->hcon->type == LE_LINK) {
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001223 if (smp_conn_security(conn, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001224 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001225
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001226 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001227 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001228 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001229 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001230 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001231 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001232 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001233
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001234 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001235 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001236
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001237 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001238 }
1239
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001240 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001241}
1242
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001243/* Notify sockets that we cannot guaranty reliability anymore */
1244static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1245{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001246 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001247
1248 BT_DBG("conn %p", conn);
1249
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001250 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001251
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001252 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001253 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001254 __l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001255 }
1256
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001257 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001258}
1259
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001260static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001261{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001262 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001263 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001264
Marcel Holtmann984947d2009-02-06 23:35:19 +01001265 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001266 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001267
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001268 l2cap_conn_start(conn);
1269}
1270
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001271static void l2cap_conn_del(struct hci_conn *hcon, int err)
1272{
1273 struct l2cap_conn *conn = hcon->l2cap_data;
1274 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001275
1276 if (!conn)
1277 return;
1278
1279 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1280
1281 kfree_skb(conn->rx_skb);
1282
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001283 mutex_lock(&conn->chan_lock);
1284
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001285 /* Kill channels */
1286 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001287 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001288 l2cap_chan_lock(chan);
1289
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001290 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001291
1292 l2cap_chan_unlock(chan);
1293
Gustavo Padovan80b98022012-05-27 22:27:51 -03001294 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001295 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001296 }
1297
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001298 mutex_unlock(&conn->chan_lock);
1299
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001300 hci_chan_del(conn->hchan);
1301
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001302 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001303 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001304
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001305 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001306 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001307 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001308 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001309
1310 hcon->l2cap_data = NULL;
1311 kfree(conn);
1312}
1313
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001314static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001315{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001316 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
1317 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001318
Johan Hedbergd06cc412012-06-06 18:44:11 +08001319 BT_DBG("conn %p", conn);
1320
1321 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1322 smp_chan_destroy(conn);
1323 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1324 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001325}
1326
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
1328{
Marcel Holtmann01394182006-07-03 10:02:46 +02001329 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001330 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331
Marcel Holtmann01394182006-07-03 10:02:46 +02001332 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001333 return conn;
1334
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001335 hchan = hci_chan_create(hcon);
1336 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001338
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001339 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
1340 if (!conn) {
1341 hci_chan_del(hchan);
1342 return NULL;
1343 }
1344
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345 hcon->l2cap_data = conn;
1346 conn->hcon = hcon;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001347 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001349 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001350
Ville Tervoacd7d372011-02-10 22:38:49 -03001351 if (hcon->hdev->le_mtu && hcon->type == LE_LINK)
1352 conn->mtu = hcon->hdev->le_mtu;
1353 else
1354 conn->mtu = hcon->hdev->acl_mtu;
1355
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356 conn->src = &hcon->hdev->bdaddr;
1357 conn->dst = &hcon->dst;
1358
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001359 conn->feat_mask = 0;
1360
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001362 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001363
1364 INIT_LIST_HEAD(&conn->chan_l);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001366 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001367 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001368 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001369 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001370
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001371 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001372
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373 return conn;
1374}
1375
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377
Ido Yarivc2287682012-04-20 15:46:07 -03001378/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379 * Returns closest match.
1380 */
Ido Yarivc2287682012-04-20 15:46:07 -03001381static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1382 bdaddr_t *src,
1383 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001385 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001387 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001388
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001389 list_for_each_entry(c, &chan_list, global_l) {
1390 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001391
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001392 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393 continue;
1394
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001395 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001396 int src_match, dst_match;
1397 int src_any, dst_any;
1398
Linus Torvalds1da177e2005-04-16 15:20:36 -07001399 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001400 src_match = !bacmp(&bt_sk(sk)->src, src);
1401 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1402 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001403 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001404 return c;
1405 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406
1407 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001408 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1409 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1410 if ((src_match && dst_any) || (src_any && dst_match) ||
1411 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001412 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413 }
1414 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001416 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001417
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001418 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419}
1420
Andre Guedes8e9f9892012-04-24 21:02:55 -03001421int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1422 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001424 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426 struct l2cap_conn *conn;
1427 struct hci_conn *hcon;
1428 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001429 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001430 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431
Andre Guedes8e9f9892012-04-24 21:02:55 -03001432 BT_DBG("%s -> %s (type %u) psm 0x%2.2x", batostr(src), batostr(dst),
1433 dst_type, __le16_to_cpu(chan->psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001435 hdev = hci_get_route(dst, src);
1436 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437 return -EHOSTUNREACH;
1438
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001439 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001440
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001441 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001442
1443 /* PSM must be odd and lsb of upper byte must be 0 */
1444 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
1445 chan->chan_type != L2CAP_CHAN_RAW) {
1446 err = -EINVAL;
1447 goto done;
1448 }
1449
1450 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1451 err = -EINVAL;
1452 goto done;
1453 }
1454
1455 switch (chan->mode) {
1456 case L2CAP_MODE_BASIC:
1457 break;
1458 case L2CAP_MODE_ERTM:
1459 case L2CAP_MODE_STREAMING:
1460 if (!disable_ertm)
1461 break;
1462 /* fall through */
1463 default:
1464 err = -ENOTSUPP;
1465 goto done;
1466 }
1467
Gustavo Padovan0797e012012-05-27 22:27:54 -03001468 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001469 case BT_CONNECT:
1470 case BT_CONNECT2:
1471 case BT_CONFIG:
1472 /* Already connecting */
1473 err = 0;
1474 goto done;
1475
1476 case BT_CONNECTED:
1477 /* Already connected */
1478 err = -EISCONN;
1479 goto done;
1480
1481 case BT_OPEN:
1482 case BT_BOUND:
1483 /* Can connect */
1484 break;
1485
1486 default:
1487 err = -EBADFD;
1488 goto done;
1489 }
1490
1491 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001492 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001493 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001494 release_sock(sk);
1495
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001496 chan->psm = psm;
1497 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001499 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001500
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001501 if (chan->dcid == L2CAP_CID_LE_DATA)
Andre Guedes8e9f9892012-04-24 21:02:55 -03001502 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001503 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001504 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001505 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001506 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001507
Ville Tervo30e76272011-02-22 16:10:53 -03001508 if (IS_ERR(hcon)) {
1509 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001511 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512
1513 conn = l2cap_conn_add(hcon, 0);
1514 if (!conn) {
1515 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001516 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517 goto done;
1518 }
1519
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001520 if (hcon->type == LE_LINK) {
1521 err = 0;
1522
1523 if (!list_empty(&conn->chan_l)) {
1524 err = -EBUSY;
1525 hci_conn_put(hcon);
1526 }
1527
1528 if (err)
1529 goto done;
1530 }
1531
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532 /* Update source addr of the socket */
1533 bacpy(src, conn->src);
1534
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001535 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001536 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001537 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001538
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001539 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001540 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541
1542 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001543 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001544 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001545 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001546 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001547 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001548 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549 }
1550
Ville Tervo30e76272011-02-22 16:10:53 -03001551 err = 0;
1552
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001554 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001555 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556 hci_dev_put(hdev);
1557 return err;
1558}
1559
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001560int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001561{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001562 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001563 DECLARE_WAITQUEUE(wait, current);
1564 int err = 0;
1565 int timeo = HZ/5;
1566
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001567 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001568 set_current_state(TASK_INTERRUPTIBLE);
1569 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001570 if (!timeo)
1571 timeo = HZ/5;
1572
1573 if (signal_pending(current)) {
1574 err = sock_intr_errno(timeo);
1575 break;
1576 }
1577
1578 release_sock(sk);
1579 timeo = schedule_timeout(timeo);
1580 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001581 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001582
1583 err = sock_error(sk);
1584 if (err)
1585 break;
1586 }
1587 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001588 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001589 return err;
1590}
1591
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001592static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001593{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001594 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001595 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001596
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001597 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001598
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001599 l2cap_chan_lock(chan);
1600
Mat Martineau80909e02012-05-17 20:53:50 -07001601 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001602 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001603 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001604 return;
1605 }
1606
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001607 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001608
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001609 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001610 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001611}
1612
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001613static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001614{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001615 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001616 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001617
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001618 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001619
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001620 l2cap_chan_lock(chan);
1621
Mat Martineau80909e02012-05-17 20:53:50 -07001622 if (!chan->conn) {
1623 l2cap_chan_unlock(chan);
1624 l2cap_chan_put(chan);
1625 return;
1626 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001627
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001628 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001629 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001630 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001631}
1632
Gustavo Padovand6603662012-05-21 13:58:22 -03001633static void l2cap_streaming_send(struct l2cap_chan *chan,
1634 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001635{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001636 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001637 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001638
Mat Martineau37339372012-05-17 20:53:33 -07001639 BT_DBG("chan %p, skbs %p", chan, skbs);
1640
Mat Martineau37339372012-05-17 20:53:33 -07001641 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1642
1643 while (!skb_queue_empty(&chan->tx_q)) {
1644
1645 skb = skb_dequeue(&chan->tx_q);
1646
1647 bt_cb(skb)->control.retries = 1;
1648 control = &bt_cb(skb)->control;
1649
1650 control->reqseq = 0;
1651 control->txseq = chan->next_tx_seq;
1652
1653 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001654
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001655 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001656 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1657 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001658 }
1659
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001660 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001661
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001662 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001663
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001664 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001665 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001666 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001667}
1668
Szymon Janc67c9e842011-07-28 16:24:33 +02001669static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001670{
1671 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001672 struct l2cap_ctrl *control;
1673 int sent = 0;
1674
1675 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001676
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001677 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001678 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001679
Mat Martineau94122bb2012-05-02 09:42:02 -07001680 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1681 return 0;
1682
Mat Martineau18a48e72012-05-17 20:53:34 -07001683 while (chan->tx_send_head &&
1684 chan->unacked_frames < chan->remote_tx_win &&
1685 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001686
Mat Martineau18a48e72012-05-17 20:53:34 -07001687 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001688
Mat Martineau18a48e72012-05-17 20:53:34 -07001689 bt_cb(skb)->control.retries = 1;
1690 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001691
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001692 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001693 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001694
Mat Martineau18a48e72012-05-17 20:53:34 -07001695 control->reqseq = chan->buffer_seq;
1696 chan->last_acked_seq = chan->buffer_seq;
1697 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001698
Mat Martineau18a48e72012-05-17 20:53:34 -07001699 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001700
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001701 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001702 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1703 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001704 }
1705
Mat Martineau18a48e72012-05-17 20:53:34 -07001706 /* Clone after data has been modified. Data is assumed to be
1707 read-only (for locking purposes) on cloned sk_buffs.
1708 */
1709 tx_skb = skb_clone(skb, GFP_KERNEL);
1710
1711 if (!tx_skb)
1712 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001713
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001714 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001715
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001716 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07001717 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03001718 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07001719 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001720
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001721 if (skb_queue_is_last(&chan->tx_q, skb))
1722 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001723 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001724 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07001725
1726 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001727 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001728 }
1729
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001730 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
1731 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07001732
1733 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001734}
1735
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001736static void l2cap_ertm_resend(struct l2cap_chan *chan)
1737{
1738 struct l2cap_ctrl control;
1739 struct sk_buff *skb;
1740 struct sk_buff *tx_skb;
1741 u16 seq;
1742
1743 BT_DBG("chan %p", chan);
1744
1745 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1746 return;
1747
1748 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
1749 seq = l2cap_seq_list_pop(&chan->retrans_list);
1750
1751 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
1752 if (!skb) {
1753 BT_DBG("Error: Can't retransmit seq %d, frame missing",
1754 seq);
1755 continue;
1756 }
1757
1758 bt_cb(skb)->control.retries++;
1759 control = bt_cb(skb)->control;
1760
1761 if (chan->max_tx != 0 &&
1762 bt_cb(skb)->control.retries > chan->max_tx) {
1763 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
1764 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
1765 l2cap_seq_list_clear(&chan->retrans_list);
1766 break;
1767 }
1768
1769 control.reqseq = chan->buffer_seq;
1770 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
1771 control.final = 1;
1772 else
1773 control.final = 0;
1774
1775 if (skb_cloned(skb)) {
1776 /* Cloned sk_buffs are read-only, so we need a
1777 * writeable copy
1778 */
1779 tx_skb = skb_copy(skb, GFP_ATOMIC);
1780 } else {
1781 tx_skb = skb_clone(skb, GFP_ATOMIC);
1782 }
1783
1784 if (!tx_skb) {
1785 l2cap_seq_list_clear(&chan->retrans_list);
1786 break;
1787 }
1788
1789 /* Update skb contents */
1790 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
1791 put_unaligned_le32(__pack_extended_control(&control),
1792 tx_skb->data + L2CAP_HDR_SIZE);
1793 } else {
1794 put_unaligned_le16(__pack_enhanced_control(&control),
1795 tx_skb->data + L2CAP_HDR_SIZE);
1796 }
1797
1798 if (chan->fcs == L2CAP_FCS_CRC16) {
1799 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
1800 put_unaligned_le16(fcs, skb_put(tx_skb,
1801 L2CAP_FCS_SIZE));
1802 }
1803
1804 l2cap_do_send(chan, tx_skb);
1805
1806 BT_DBG("Resent txseq %d", control.txseq);
1807
1808 chan->last_acked_seq = chan->buffer_seq;
1809 }
1810}
1811
Mat Martineauf80842a2012-05-17 20:53:46 -07001812static void l2cap_retransmit(struct l2cap_chan *chan,
1813 struct l2cap_ctrl *control)
1814{
1815 BT_DBG("chan %p, control %p", chan, control);
1816
1817 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
1818 l2cap_ertm_resend(chan);
1819}
1820
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001821static void l2cap_retransmit_all(struct l2cap_chan *chan,
1822 struct l2cap_ctrl *control)
1823{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001824 struct sk_buff *skb;
1825
1826 BT_DBG("chan %p, control %p", chan, control);
1827
1828 if (control->poll)
1829 set_bit(CONN_SEND_FBIT, &chan->conn_state);
1830
1831 l2cap_seq_list_clear(&chan->retrans_list);
1832
1833 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1834 return;
1835
1836 if (chan->unacked_frames) {
1837 skb_queue_walk(&chan->tx_q, skb) {
1838 if (bt_cb(skb)->control.txseq == control->reqseq ||
1839 skb == chan->tx_send_head)
1840 break;
1841 }
1842
1843 skb_queue_walk_from(&chan->tx_q, skb) {
1844 if (skb == chan->tx_send_head)
1845 break;
1846
1847 l2cap_seq_list_append(&chan->retrans_list,
1848 bt_cb(skb)->control.txseq);
1849 }
1850
1851 l2cap_ertm_resend(chan);
1852 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001853}
1854
Szymon Jancb17e73b2012-01-11 10:59:47 +01001855static void l2cap_send_ack(struct l2cap_chan *chan)
1856{
Mat Martineau0a0aba42012-05-17 20:53:39 -07001857 struct l2cap_ctrl control;
1858 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
1859 chan->last_acked_seq);
1860 int threshold;
1861
1862 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
1863 chan, chan->last_acked_seq, chan->buffer_seq);
1864
1865 memset(&control, 0, sizeof(control));
1866 control.sframe = 1;
1867
1868 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
1869 chan->rx_state == L2CAP_RX_STATE_RECV) {
1870 __clear_ack_timer(chan);
1871 control.super = L2CAP_SUPER_RNR;
1872 control.reqseq = chan->buffer_seq;
1873 l2cap_send_sframe(chan, &control);
1874 } else {
1875 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
1876 l2cap_ertm_send(chan);
1877 /* If any i-frames were sent, they included an ack */
1878 if (chan->buffer_seq == chan->last_acked_seq)
1879 frames_to_ack = 0;
1880 }
1881
Mat Martineauc20f8e32012-07-10 05:47:07 -07001882 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07001883 * Calculate without mul or div
1884 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07001885 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07001886 threshold += threshold << 1;
1887 threshold >>= 2;
1888
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001889 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07001890 threshold);
1891
1892 if (frames_to_ack >= threshold) {
1893 __clear_ack_timer(chan);
1894 control.super = L2CAP_SUPER_RR;
1895 control.reqseq = chan->buffer_seq;
1896 l2cap_send_sframe(chan, &control);
1897 frames_to_ack = 0;
1898 }
1899
1900 if (frames_to_ack)
1901 __set_ack_timer(chan);
1902 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01001903}
1904
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001905static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
1906 struct msghdr *msg, int len,
1907 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02001909 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001910 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03001911 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001913 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001914 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915
1916 sent += count;
1917 len -= count;
1918
1919 /* Continuation fragments (no L2CAP header) */
1920 frag = &skb_shinfo(skb)->frag_list;
1921 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001922 struct sk_buff *tmp;
1923
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924 count = min_t(unsigned int, conn->mtu, len);
1925
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001926 tmp = chan->ops->alloc_skb(chan, count,
1927 msg->msg_flags & MSG_DONTWAIT);
1928 if (IS_ERR(tmp))
1929 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001930
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001931 *frag = tmp;
1932
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001933 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1934 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001936 (*frag)->priority = skb->priority;
1937
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938 sent += count;
1939 len -= count;
1940
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03001941 skb->len += (*frag)->len;
1942 skb->data_len += (*frag)->len;
1943
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944 frag = &(*frag)->next;
1945 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946
1947 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001948}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001950static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001951 struct msghdr *msg, size_t len,
1952 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001953{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001954 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001955 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03001956 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001957 struct l2cap_hdr *lh;
1958
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001959 BT_DBG("chan %p len %zu priority %u", chan, len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001960
1961 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001962
1963 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03001964 msg->msg_flags & MSG_DONTWAIT);
1965 if (IS_ERR(skb))
1966 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001967
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001968 skb->priority = priority;
1969
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001970 /* Create L2CAP header */
1971 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001972 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03001973 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
1974 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001975
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02001976 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001977 if (unlikely(err < 0)) {
1978 kfree_skb(skb);
1979 return ERR_PTR(err);
1980 }
1981 return skb;
1982}
1983
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001984static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001985 struct msghdr *msg, size_t len,
1986 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001987{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001988 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001989 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03001990 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001991 struct l2cap_hdr *lh;
1992
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001993 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001994
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03001995 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001996
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03001997 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03001998 msg->msg_flags & MSG_DONTWAIT);
1999 if (IS_ERR(skb))
2000 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002001
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002002 skb->priority = priority;
2003
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002004 /* Create L2CAP header */
2005 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002006 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002007 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002008
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002009 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002010 if (unlikely(err < 0)) {
2011 kfree_skb(skb);
2012 return ERR_PTR(err);
2013 }
2014 return skb;
2015}
2016
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002017static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002018 struct msghdr *msg, size_t len,
2019 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002020{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002021 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002022 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002023 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002024 struct l2cap_hdr *lh;
2025
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002026 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002027
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002028 if (!conn)
2029 return ERR_PTR(-ENOTCONN);
2030
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002031 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002032
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002033 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002034 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002035
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002036 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002037 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002038
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002039 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002040
2041 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002042 msg->msg_flags & MSG_DONTWAIT);
2043 if (IS_ERR(skb))
2044 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002045
2046 /* 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 F. Padovan1c2acff2009-08-20 22:25:57 -03002049 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002050
Mat Martineau18a48e72012-05-17 20:53:34 -07002051 /* Control header is populated later */
2052 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2053 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2054 else
2055 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002056
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002057 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002058 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002059
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002060 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002061 if (unlikely(err < 0)) {
2062 kfree_skb(skb);
2063 return ERR_PTR(err);
2064 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002065
Mat Martineau18a48e72012-05-17 20:53:34 -07002066 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002067 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002068 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002069}
2070
Mat Martineau94122bb2012-05-02 09:42:02 -07002071static int l2cap_segment_sdu(struct l2cap_chan *chan,
2072 struct sk_buff_head *seg_queue,
2073 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002074{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002075 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002076 u16 sdu_len;
2077 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002078 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002079
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002080 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002081
Mat Martineau94122bb2012-05-02 09:42:02 -07002082 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2083 * so fragmented skbs are not used. The HCI layer's handling
2084 * of fragmented skbs is not compatible with ERTM's queueing.
2085 */
2086
2087 /* PDU size is derived from the HCI MTU */
2088 pdu_len = chan->conn->mtu;
2089
2090 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
2091
2092 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002093 if (chan->fcs)
2094 pdu_len -= L2CAP_FCS_SIZE;
2095
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002096 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002097
2098 /* Remote device may have requested smaller PDUs */
2099 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2100
2101 if (len <= pdu_len) {
2102 sar = L2CAP_SAR_UNSEGMENTED;
2103 sdu_len = 0;
2104 pdu_len = len;
2105 } else {
2106 sar = L2CAP_SAR_START;
2107 sdu_len = len;
2108 pdu_len -= L2CAP_SDULEN_SIZE;
2109 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002110
2111 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002112 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002113
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002114 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002115 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002116 return PTR_ERR(skb);
2117 }
2118
Mat Martineau94122bb2012-05-02 09:42:02 -07002119 bt_cb(skb)->control.sar = sar;
2120 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002121
Mat Martineau94122bb2012-05-02 09:42:02 -07002122 len -= pdu_len;
2123 if (sdu_len) {
2124 sdu_len = 0;
2125 pdu_len += L2CAP_SDULEN_SIZE;
2126 }
2127
2128 if (len <= pdu_len) {
2129 sar = L2CAP_SAR_END;
2130 pdu_len = len;
2131 } else {
2132 sar = L2CAP_SAR_CONTINUE;
2133 }
2134 }
2135
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002136 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002137}
2138
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002139int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
2140 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002141{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002142 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002143 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002144 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002145
2146 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002147 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002148 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002149 if (IS_ERR(skb))
2150 return PTR_ERR(skb);
2151
2152 l2cap_do_send(chan, skb);
2153 return len;
2154 }
2155
2156 switch (chan->mode) {
2157 case L2CAP_MODE_BASIC:
2158 /* Check outgoing MTU */
2159 if (len > chan->omtu)
2160 return -EMSGSIZE;
2161
2162 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002163 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002164 if (IS_ERR(skb))
2165 return PTR_ERR(skb);
2166
2167 l2cap_do_send(chan, skb);
2168 err = len;
2169 break;
2170
2171 case L2CAP_MODE_ERTM:
2172 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002173 /* Check outgoing MTU */
2174 if (len > chan->omtu) {
2175 err = -EMSGSIZE;
2176 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002177 }
2178
Mat Martineau94122bb2012-05-02 09:42:02 -07002179 __skb_queue_head_init(&seg_queue);
2180
2181 /* Do segmentation before calling in to the state machine,
2182 * since it's possible to block while waiting for memory
2183 * allocation.
2184 */
2185 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2186
2187 /* The channel could have been closed while segmenting,
2188 * check that it is still connected.
2189 */
2190 if (chan->state != BT_CONNECTED) {
2191 __skb_queue_purge(&seg_queue);
2192 err = -ENOTCONN;
2193 }
2194
2195 if (err)
2196 break;
2197
Mat Martineau37339372012-05-17 20:53:33 -07002198 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002199 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002200 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002201 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002202
Gustavo Padovand6603662012-05-21 13:58:22 -03002203 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002204
Mat Martineau94122bb2012-05-02 09:42:02 -07002205 /* If the skbs were not queued for sending, they'll still be in
2206 * seg_queue and need to be purged.
2207 */
2208 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002209 break;
2210
2211 default:
2212 BT_DBG("bad state %1.1x", chan->mode);
2213 err = -EBADFD;
2214 }
2215
2216 return err;
2217}
2218
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002219static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2220{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002221 struct l2cap_ctrl control;
2222 u16 seq;
2223
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002224 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002225
2226 memset(&control, 0, sizeof(control));
2227 control.sframe = 1;
2228 control.super = L2CAP_SUPER_SREJ;
2229
2230 for (seq = chan->expected_tx_seq; seq != txseq;
2231 seq = __next_seq(chan, seq)) {
2232 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2233 control.reqseq = seq;
2234 l2cap_send_sframe(chan, &control);
2235 l2cap_seq_list_append(&chan->srej_list, seq);
2236 }
2237 }
2238
2239 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002240}
2241
2242static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2243{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002244 struct l2cap_ctrl control;
2245
2246 BT_DBG("chan %p", chan);
2247
2248 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2249 return;
2250
2251 memset(&control, 0, sizeof(control));
2252 control.sframe = 1;
2253 control.super = L2CAP_SUPER_SREJ;
2254 control.reqseq = chan->srej_list.tail;
2255 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002256}
2257
2258static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2259{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002260 struct l2cap_ctrl control;
2261 u16 initial_head;
2262 u16 seq;
2263
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002264 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002265
2266 memset(&control, 0, sizeof(control));
2267 control.sframe = 1;
2268 control.super = L2CAP_SUPER_SREJ;
2269
2270 /* Capture initial list head to allow only one pass through the list. */
2271 initial_head = chan->srej_list.head;
2272
2273 do {
2274 seq = l2cap_seq_list_pop(&chan->srej_list);
2275 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2276 break;
2277
2278 control.reqseq = seq;
2279 l2cap_send_sframe(chan, &control);
2280 l2cap_seq_list_append(&chan->srej_list, seq);
2281 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002282}
2283
Mat Martineau608bcc62012-05-17 20:53:32 -07002284static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2285{
2286 struct sk_buff *acked_skb;
2287 u16 ackseq;
2288
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002289 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002290
2291 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2292 return;
2293
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002294 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002295 chan->expected_ack_seq, chan->unacked_frames);
2296
2297 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2298 ackseq = __next_seq(chan, ackseq)) {
2299
2300 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2301 if (acked_skb) {
2302 skb_unlink(acked_skb, &chan->tx_q);
2303 kfree_skb(acked_skb);
2304 chan->unacked_frames--;
2305 }
2306 }
2307
2308 chan->expected_ack_seq = reqseq;
2309
2310 if (chan->unacked_frames == 0)
2311 __clear_retrans_timer(chan);
2312
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002313 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002314}
2315
2316static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2317{
2318 BT_DBG("chan %p", chan);
2319
2320 chan->expected_tx_seq = chan->buffer_seq;
2321 l2cap_seq_list_clear(&chan->srej_list);
2322 skb_queue_purge(&chan->srej_q);
2323 chan->rx_state = L2CAP_RX_STATE_RECV;
2324}
2325
Gustavo Padovand6603662012-05-21 13:58:22 -03002326static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2327 struct l2cap_ctrl *control,
2328 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002329{
Mat Martineau608bcc62012-05-17 20:53:32 -07002330 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2331 event);
2332
2333 switch (event) {
2334 case L2CAP_EV_DATA_REQUEST:
2335 if (chan->tx_send_head == NULL)
2336 chan->tx_send_head = skb_peek(skbs);
2337
2338 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2339 l2cap_ertm_send(chan);
2340 break;
2341 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2342 BT_DBG("Enter LOCAL_BUSY");
2343 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2344
2345 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2346 /* The SREJ_SENT state must be aborted if we are to
2347 * enter the LOCAL_BUSY state.
2348 */
2349 l2cap_abort_rx_srej_sent(chan);
2350 }
2351
2352 l2cap_send_ack(chan);
2353
2354 break;
2355 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2356 BT_DBG("Exit LOCAL_BUSY");
2357 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2358
2359 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2360 struct l2cap_ctrl local_control;
2361
2362 memset(&local_control, 0, sizeof(local_control));
2363 local_control.sframe = 1;
2364 local_control.super = L2CAP_SUPER_RR;
2365 local_control.poll = 1;
2366 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002367 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002368
2369 chan->retry_count = 1;
2370 __set_monitor_timer(chan);
2371 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2372 }
2373 break;
2374 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2375 l2cap_process_reqseq(chan, control->reqseq);
2376 break;
2377 case L2CAP_EV_EXPLICIT_POLL:
2378 l2cap_send_rr_or_rnr(chan, 1);
2379 chan->retry_count = 1;
2380 __set_monitor_timer(chan);
2381 __clear_ack_timer(chan);
2382 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2383 break;
2384 case L2CAP_EV_RETRANS_TO:
2385 l2cap_send_rr_or_rnr(chan, 1);
2386 chan->retry_count = 1;
2387 __set_monitor_timer(chan);
2388 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2389 break;
2390 case L2CAP_EV_RECV_FBIT:
2391 /* Nothing to process */
2392 break;
2393 default:
2394 break;
2395 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002396}
2397
Gustavo Padovand6603662012-05-21 13:58:22 -03002398static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2399 struct l2cap_ctrl *control,
2400 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002401{
Mat Martineau608bcc62012-05-17 20:53:32 -07002402 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2403 event);
2404
2405 switch (event) {
2406 case L2CAP_EV_DATA_REQUEST:
2407 if (chan->tx_send_head == NULL)
2408 chan->tx_send_head = skb_peek(skbs);
2409 /* Queue data, but don't send. */
2410 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2411 break;
2412 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2413 BT_DBG("Enter LOCAL_BUSY");
2414 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2415
2416 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2417 /* The SREJ_SENT state must be aborted if we are to
2418 * enter the LOCAL_BUSY state.
2419 */
2420 l2cap_abort_rx_srej_sent(chan);
2421 }
2422
2423 l2cap_send_ack(chan);
2424
2425 break;
2426 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2427 BT_DBG("Exit LOCAL_BUSY");
2428 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2429
2430 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2431 struct l2cap_ctrl local_control;
2432 memset(&local_control, 0, sizeof(local_control));
2433 local_control.sframe = 1;
2434 local_control.super = L2CAP_SUPER_RR;
2435 local_control.poll = 1;
2436 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002437 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002438
2439 chan->retry_count = 1;
2440 __set_monitor_timer(chan);
2441 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2442 }
2443 break;
2444 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2445 l2cap_process_reqseq(chan, control->reqseq);
2446
2447 /* Fall through */
2448
2449 case L2CAP_EV_RECV_FBIT:
2450 if (control && control->final) {
2451 __clear_monitor_timer(chan);
2452 if (chan->unacked_frames > 0)
2453 __set_retrans_timer(chan);
2454 chan->retry_count = 0;
2455 chan->tx_state = L2CAP_TX_STATE_XMIT;
2456 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2457 }
2458 break;
2459 case L2CAP_EV_EXPLICIT_POLL:
2460 /* Ignore */
2461 break;
2462 case L2CAP_EV_MONITOR_TO:
2463 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2464 l2cap_send_rr_or_rnr(chan, 1);
2465 __set_monitor_timer(chan);
2466 chan->retry_count++;
2467 } else {
2468 l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
2469 }
2470 break;
2471 default:
2472 break;
2473 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002474}
2475
Gustavo Padovand6603662012-05-21 13:58:22 -03002476static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2477 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002478{
Mat Martineau608bcc62012-05-17 20:53:32 -07002479 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2480 chan, control, skbs, event, chan->tx_state);
2481
2482 switch (chan->tx_state) {
2483 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002484 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002485 break;
2486 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002487 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002488 break;
2489 default:
2490 /* Ignore event */
2491 break;
2492 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002493}
2494
Mat Martineau4b51dae92012-05-17 20:53:37 -07002495static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2496 struct l2cap_ctrl *control)
2497{
2498 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002499 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002500}
2501
Mat Martineauf80842a2012-05-17 20:53:46 -07002502static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2503 struct l2cap_ctrl *control)
2504{
2505 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002506 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002507}
2508
Linus Torvalds1da177e2005-04-16 15:20:36 -07002509/* Copy frame to all raw sockets on that connection */
2510static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2511{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002512 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002513 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002514
2515 BT_DBG("conn %p", conn);
2516
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002517 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002518
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002519 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002520 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002521 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002522 continue;
2523
2524 /* Don't send frame to the socket it came from */
2525 if (skb->sk == sk)
2526 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002527 nskb = skb_clone(skb, GFP_ATOMIC);
2528 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002529 continue;
2530
Gustavo Padovan80b98022012-05-27 22:27:51 -03002531 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002532 kfree_skb(nskb);
2533 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002534
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002535 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002536}
2537
2538/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002539static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2540 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002541{
2542 struct sk_buff *skb, **frag;
2543 struct l2cap_cmd_hdr *cmd;
2544 struct l2cap_hdr *lh;
2545 int len, count;
2546
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002547 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2548 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002549
2550 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2551 count = min_t(unsigned int, conn->mtu, len);
2552
2553 skb = bt_skb_alloc(count, GFP_ATOMIC);
2554 if (!skb)
2555 return NULL;
2556
2557 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002558 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002559
2560 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002561 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002562 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002563 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002564
2565 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2566 cmd->code = code;
2567 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002568 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002569
2570 if (dlen) {
2571 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2572 memcpy(skb_put(skb, count), data, count);
2573 data += count;
2574 }
2575
2576 len -= skb->len;
2577
2578 /* Continuation fragments (no L2CAP header) */
2579 frag = &skb_shinfo(skb)->frag_list;
2580 while (len) {
2581 count = min_t(unsigned int, conn->mtu, len);
2582
2583 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2584 if (!*frag)
2585 goto fail;
2586
2587 memcpy(skb_put(*frag, count), data, count);
2588
2589 len -= count;
2590 data += count;
2591
2592 frag = &(*frag)->next;
2593 }
2594
2595 return skb;
2596
2597fail:
2598 kfree_skb(skb);
2599 return NULL;
2600}
2601
2602static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2603{
2604 struct l2cap_conf_opt *opt = *ptr;
2605 int len;
2606
2607 len = L2CAP_CONF_OPT_SIZE + opt->len;
2608 *ptr += len;
2609
2610 *type = opt->type;
2611 *olen = opt->len;
2612
2613 switch (opt->len) {
2614 case 1:
2615 *val = *((u8 *) opt->val);
2616 break;
2617
2618 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002619 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002620 break;
2621
2622 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002623 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002624 break;
2625
2626 default:
2627 *val = (unsigned long) opt->val;
2628 break;
2629 }
2630
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002631 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002632 return len;
2633}
2634
Linus Torvalds1da177e2005-04-16 15:20:36 -07002635static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2636{
2637 struct l2cap_conf_opt *opt = *ptr;
2638
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002639 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002640
2641 opt->type = type;
2642 opt->len = len;
2643
2644 switch (len) {
2645 case 1:
2646 *((u8 *) opt->val) = val;
2647 break;
2648
2649 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002650 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002651 break;
2652
2653 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002654 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002655 break;
2656
2657 default:
2658 memcpy(opt->val, (void *) val, len);
2659 break;
2660 }
2661
2662 *ptr += L2CAP_CONF_OPT_SIZE + len;
2663}
2664
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002665static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2666{
2667 struct l2cap_conf_efs efs;
2668
Szymon Janc1ec918c2011-11-16 09:32:21 +01002669 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002670 case L2CAP_MODE_ERTM:
2671 efs.id = chan->local_id;
2672 efs.stype = chan->local_stype;
2673 efs.msdu = cpu_to_le16(chan->local_msdu);
2674 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002675 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
2676 efs.flush_to = __constant_cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002677 break;
2678
2679 case L2CAP_MODE_STREAMING:
2680 efs.id = 1;
2681 efs.stype = L2CAP_SERV_BESTEFFORT;
2682 efs.msdu = cpu_to_le16(chan->local_msdu);
2683 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2684 efs.acc_lat = 0;
2685 efs.flush_to = 0;
2686 break;
2687
2688 default:
2689 return;
2690 }
2691
2692 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
2693 (unsigned long) &efs);
2694}
2695
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002696static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002697{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002698 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07002699 ack_timer.work);
2700 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002701
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02002702 BT_DBG("chan %p", chan);
2703
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002704 l2cap_chan_lock(chan);
2705
Mat Martineau03625202012-05-17 20:53:51 -07002706 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2707 chan->last_acked_seq);
2708
2709 if (frames_to_ack)
2710 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002711
2712 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01002713 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002714}
2715
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03002716int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002717{
Mat Martineau3c588192012-04-11 10:48:42 -07002718 int err;
2719
Mat Martineau105bdf92012-04-27 16:50:48 -07002720 chan->next_tx_seq = 0;
2721 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002722 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002723 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002724 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002725 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07002726 chan->last_acked_seq = 0;
2727 chan->sdu = NULL;
2728 chan->sdu_last_frag = NULL;
2729 chan->sdu_len = 0;
2730
Mat Martineaud34c34f2012-05-14 14:49:27 -07002731 skb_queue_head_init(&chan->tx_q);
2732
Mat Martineau105bdf92012-04-27 16:50:48 -07002733 if (chan->mode != L2CAP_MODE_ERTM)
2734 return 0;
2735
2736 chan->rx_state = L2CAP_RX_STATE_RECV;
2737 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002738
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002739 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
2740 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
2741 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002742
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03002743 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002744
Mat Martineau3c588192012-04-11 10:48:42 -07002745 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
2746 if (err < 0)
2747 return err;
2748
Mat Martineau9dc9aff2012-05-17 16:20:14 -07002749 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
2750 if (err < 0)
2751 l2cap_seq_list_free(&chan->srej_list);
2752
2753 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002754}
2755
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002756static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2757{
2758 switch (mode) {
2759 case L2CAP_MODE_STREAMING:
2760 case L2CAP_MODE_ERTM:
2761 if (l2cap_mode_supported(mode, remote_feat_mask))
2762 return mode;
2763 /* fall through */
2764 default:
2765 return L2CAP_MODE_BASIC;
2766 }
2767}
2768
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002769static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
2770{
2771 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
2772}
2773
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002774static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
2775{
2776 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
2777}
2778
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002779static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
2780{
2781 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002782 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002783 /* use extended control field */
2784 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002785 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
2786 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002787 chan->tx_win = min_t(u16, chan->tx_win,
2788 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002789 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
2790 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07002791 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002792}
2793
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03002794static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002795{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002796 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002797 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002798 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002799 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002800
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03002801 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002802
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002803 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002804 goto done;
2805
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002806 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002807 case L2CAP_MODE_STREAMING:
2808 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002809 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002810 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002811
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002812 if (__l2cap_efs_supported(chan))
2813 set_bit(FLAG_EFS_ENABLE, &chan->flags);
2814
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002815 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002816 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002817 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002818 break;
2819 }
2820
2821done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002822 if (chan->imtu != L2CAP_DEFAULT_MTU)
2823 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02002824
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002825 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002826 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002827 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
2828 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002829 break;
2830
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002831 rfc.mode = L2CAP_MODE_BASIC;
2832 rfc.txwin_size = 0;
2833 rfc.max_transmit = 0;
2834 rfc.retrans_timeout = 0;
2835 rfc.monitor_timeout = 0;
2836 rfc.max_pdu_size = 0;
2837
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002838 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2839 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002840 break;
2841
2842 case L2CAP_MODE_ERTM:
2843 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002844 rfc.max_transmit = chan->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002845 rfc.retrans_timeout = 0;
2846 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002847
2848 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
2849 L2CAP_EXT_HDR_SIZE -
2850 L2CAP_SDULEN_SIZE -
2851 L2CAP_FCS_SIZE);
2852 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002853
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002854 l2cap_txwin_setup(chan);
2855
2856 rfc.txwin_size = min_t(u16, chan->tx_win,
2857 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002858
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002859 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2860 (unsigned long) &rfc);
2861
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002862 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2863 l2cap_add_opt_efs(&ptr, chan);
2864
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002865 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002866 break;
2867
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002868 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002869 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002870 chan->fcs = L2CAP_FCS_NONE;
2871 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002872 }
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002873
2874 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2875 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
2876 chan->tx_win);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002877 break;
2878
2879 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07002880 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002881 rfc.mode = L2CAP_MODE_STREAMING;
2882 rfc.txwin_size = 0;
2883 rfc.max_transmit = 0;
2884 rfc.retrans_timeout = 0;
2885 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002886
2887 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
2888 L2CAP_EXT_HDR_SIZE -
2889 L2CAP_SDULEN_SIZE -
2890 L2CAP_FCS_SIZE);
2891 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002892
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002893 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2894 (unsigned long) &rfc);
2895
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002896 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2897 l2cap_add_opt_efs(&ptr, chan);
2898
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002899 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002900 break;
2901
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002902 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002903 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002904 chan->fcs = L2CAP_FCS_NONE;
2905 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002906 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002907 break;
2908 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002909
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002910 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03002911 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002912
2913 return ptr - data;
2914}
2915
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002916static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002917{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002918 struct l2cap_conf_rsp *rsp = data;
2919 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002920 void *req = chan->conf_req;
2921 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002922 int type, hint, olen;
2923 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002924 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002925 struct l2cap_conf_efs efs;
2926 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02002927 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002928 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002929 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002930
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002931 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002932
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002933 while (len >= L2CAP_CONF_OPT_SIZE) {
2934 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002935
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002936 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002937 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002938
2939 switch (type) {
2940 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002941 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002942 break;
2943
2944 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002945 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002946 break;
2947
2948 case L2CAP_CONF_QOS:
2949 break;
2950
Marcel Holtmann6464f352007-10-20 13:39:51 +02002951 case L2CAP_CONF_RFC:
2952 if (olen == sizeof(rfc))
2953 memcpy(&rfc, (void *) val, olen);
2954 break;
2955
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002956 case L2CAP_CONF_FCS:
2957 if (val == L2CAP_FCS_NONE)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002958 set_bit(CONF_NO_FCS_RECV, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002959 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002960
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002961 case L2CAP_CONF_EFS:
2962 remote_efs = 1;
2963 if (olen == sizeof(efs))
2964 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002965 break;
2966
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002967 case L2CAP_CONF_EWS:
2968 if (!enable_hs)
2969 return -ECONNREFUSED;
2970
2971 set_bit(FLAG_EXT_CTRL, &chan->flags);
2972 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002973 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002974 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002975 break;
2976
2977 default:
2978 if (hint)
2979 break;
2980
2981 result = L2CAP_CONF_UNKNOWN;
2982 *((u8 *) ptr++) = type;
2983 break;
2984 }
2985 }
2986
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002987 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002988 goto done;
2989
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002990 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002991 case L2CAP_MODE_STREAMING:
2992 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002993 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002994 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002995 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002996 break;
2997 }
2998
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002999 if (remote_efs) {
3000 if (__l2cap_efs_supported(chan))
3001 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3002 else
3003 return -ECONNREFUSED;
3004 }
3005
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003006 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003007 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003008
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003009 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003010 }
3011
3012done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003013 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003014 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003015 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003016
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003017 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003018 return -ECONNREFUSED;
3019
3020 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3021 sizeof(rfc), (unsigned long) &rfc);
3022 }
3023
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003024 if (result == L2CAP_CONF_SUCCESS) {
3025 /* Configure output options and let the other side know
3026 * which ones we don't like. */
3027
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003028 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3029 result = L2CAP_CONF_UNACCEPT;
3030 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003031 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003032 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003033 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003034 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003035
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003036 if (remote_efs) {
3037 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
3038 efs.stype != L2CAP_SERV_NOTRAFIC &&
3039 efs.stype != chan->local_stype) {
3040
3041 result = L2CAP_CONF_UNACCEPT;
3042
3043 if (chan->num_conf_req >= 1)
3044 return -ECONNREFUSED;
3045
3046 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003047 sizeof(efs),
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003048 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003049 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003050 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003051 result = L2CAP_CONF_PENDING;
3052 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003053 }
3054 }
3055
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003056 switch (rfc.mode) {
3057 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003058 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003059 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003060 break;
3061
3062 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003063 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3064 chan->remote_tx_win = rfc.txwin_size;
3065 else
3066 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3067
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003068 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003069
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003070 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
3071 chan->conn->mtu -
3072 L2CAP_EXT_HDR_SIZE -
3073 L2CAP_SDULEN_SIZE -
3074 L2CAP_FCS_SIZE);
3075 rfc.max_pdu_size = cpu_to_le16(size);
3076 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003077
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003078 rfc.retrans_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003079 __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003080 rfc.monitor_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003081 __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003082
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003083 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003084
3085 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3086 sizeof(rfc), (unsigned long) &rfc);
3087
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003088 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3089 chan->remote_id = efs.id;
3090 chan->remote_stype = efs.stype;
3091 chan->remote_msdu = le16_to_cpu(efs.msdu);
3092 chan->remote_flush_to =
3093 le32_to_cpu(efs.flush_to);
3094 chan->remote_acc_lat =
3095 le32_to_cpu(efs.acc_lat);
3096 chan->remote_sdu_itime =
3097 le32_to_cpu(efs.sdu_itime);
3098 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
3099 sizeof(efs), (unsigned long) &efs);
3100 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003101 break;
3102
3103 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003104 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
3105 chan->conn->mtu -
3106 L2CAP_EXT_HDR_SIZE -
3107 L2CAP_SDULEN_SIZE -
3108 L2CAP_FCS_SIZE);
3109 rfc.max_pdu_size = cpu_to_le16(size);
3110 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003111
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003112 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003113
3114 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3115 sizeof(rfc), (unsigned long) &rfc);
3116
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003117 break;
3118
3119 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003120 result = L2CAP_CONF_UNACCEPT;
3121
3122 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003123 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003124 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003125
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003126 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003127 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003128 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003129 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003130 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003131 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003132
3133 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003134}
3135
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003136static 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 -03003137{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003138 struct l2cap_conf_req *req = data;
3139 void *ptr = req->data;
3140 int type, olen;
3141 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003142 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003143 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003144
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003145 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003146
3147 while (len >= L2CAP_CONF_OPT_SIZE) {
3148 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3149
3150 switch (type) {
3151 case L2CAP_CONF_MTU:
3152 if (val < L2CAP_DEFAULT_MIN_MTU) {
3153 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003154 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003155 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003156 chan->imtu = val;
3157 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003158 break;
3159
3160 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003161 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003162 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003163 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003164 break;
3165
3166 case L2CAP_CONF_RFC:
3167 if (olen == sizeof(rfc))
3168 memcpy(&rfc, (void *)val, olen);
3169
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003170 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003171 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003172 return -ECONNREFUSED;
3173
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003174 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003175
3176 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3177 sizeof(rfc), (unsigned long) &rfc);
3178 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003179
3180 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003181 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003182 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003183 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003184 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003185
3186 case L2CAP_CONF_EFS:
3187 if (olen == sizeof(efs))
3188 memcpy(&efs, (void *)val, olen);
3189
3190 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
3191 efs.stype != L2CAP_SERV_NOTRAFIC &&
3192 efs.stype != chan->local_stype)
3193 return -ECONNREFUSED;
3194
3195 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
3196 sizeof(efs), (unsigned long) &efs);
3197 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003198 }
3199 }
3200
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003201 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003202 return -ECONNREFUSED;
3203
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003204 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003205
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003206 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003207 switch (rfc.mode) {
3208 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003209 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3210 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3211 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003212 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3213 chan->ack_win = min_t(u16, chan->ack_win,
3214 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003215
3216 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3217 chan->local_msdu = le16_to_cpu(efs.msdu);
3218 chan->local_sdu_itime =
3219 le32_to_cpu(efs.sdu_itime);
3220 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3221 chan->local_flush_to =
3222 le32_to_cpu(efs.flush_to);
3223 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003224 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003225
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003226 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003227 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003228 }
3229 }
3230
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003231 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003232 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003233
3234 return ptr - data;
3235}
3236
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003237static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003238{
3239 struct l2cap_conf_rsp *rsp = data;
3240 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003241
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003242 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003243
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003244 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003245 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003246 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003247
3248 return ptr - data;
3249}
3250
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003251void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003252{
3253 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003254 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003255 u8 buf[128];
3256
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003257 rsp.scid = cpu_to_le16(chan->dcid);
3258 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003259 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3260 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003261 l2cap_send_cmd(conn, chan->ident,
3262 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
3263
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003264 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003265 return;
3266
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003267 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3268 l2cap_build_conf_req(chan, buf), buf);
3269 chan->num_conf_req++;
3270}
3271
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003272static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003273{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003274 int type, olen;
3275 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003276 /* Use sane default values in case a misbehaving remote device
3277 * did not send an RFC or extended window size option.
3278 */
3279 u16 txwin_ext = chan->ack_win;
3280 struct l2cap_conf_rfc rfc = {
3281 .mode = chan->mode,
3282 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3283 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3284 .max_pdu_size = cpu_to_le16(chan->imtu),
3285 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3286 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003287
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003288 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003289
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003290 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003291 return;
3292
3293 while (len >= L2CAP_CONF_OPT_SIZE) {
3294 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3295
Mat Martineauc20f8e32012-07-10 05:47:07 -07003296 switch (type) {
3297 case L2CAP_CONF_RFC:
3298 if (olen == sizeof(rfc))
3299 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003300 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003301 case L2CAP_CONF_EWS:
3302 txwin_ext = val;
3303 break;
3304 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003305 }
3306
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003307 switch (rfc.mode) {
3308 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003309 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3310 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003311 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3312 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3313 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3314 else
3315 chan->ack_win = min_t(u16, chan->ack_win,
3316 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003317 break;
3318 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003319 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003320 }
3321}
3322
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003323static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3324{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003325 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003326
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003327 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003328 return 0;
3329
3330 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
3331 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003332 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003333
3334 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003335 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003336
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003337 l2cap_conn_start(conn);
3338 }
3339
3340 return 0;
3341}
3342
Linus Torvalds1da177e2005-04-16 15:20:36 -07003343static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3344{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003345 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3346 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003347 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003348 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003349 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003350
3351 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003352 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003353
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003354 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003355
3356 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003357 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003358 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003359 result = L2CAP_CR_BAD_PSM;
3360 goto sendresp;
3361 }
3362
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003363 parent = pchan->sk;
3364
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003365 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003366 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003367
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003368 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003369 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003370 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003371 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003372 result = L2CAP_CR_SEC_BLOCK;
3373 goto response;
3374 }
3375
Linus Torvalds1da177e2005-04-16 15:20:36 -07003376 result = L2CAP_CR_NO_MEM;
3377
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003378 /* Check if we already have channel with that dcid */
3379 if (__l2cap_get_chan_by_dcid(conn, scid))
3380 goto response;
3381
Gustavo Padovan80b98022012-05-27 22:27:51 -03003382 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003383 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003384 goto response;
3385
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003386 sk = chan->sk;
3387
Linus Torvalds1da177e2005-04-16 15:20:36 -07003388 hci_conn_hold(conn->hcon);
3389
Linus Torvalds1da177e2005-04-16 15:20:36 -07003390 bacpy(&bt_sk(sk)->src, conn->src);
3391 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003392 chan->psm = psm;
3393 chan->dcid = scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003394
Gustavo F. Padovand1010242011-03-25 00:39:48 -03003395 bt_accept_enqueue(parent, sk);
3396
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003397 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003398
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003399 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003400
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003401 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003402
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003403 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003404
Marcel Holtmann984947d2009-02-06 23:35:19 +01003405 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003406 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003407 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003408 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003409 result = L2CAP_CR_PEND;
3410 status = L2CAP_CS_AUTHOR_PEND;
3411 parent->sk_data_ready(parent, 0);
3412 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003413 __l2cap_state_change(chan, BT_CONFIG);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003414 result = L2CAP_CR_SUCCESS;
3415 status = L2CAP_CS_NO_INFO;
3416 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003417 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003418 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003419 result = L2CAP_CR_PEND;
3420 status = L2CAP_CS_AUTHEN_PEND;
3421 }
3422 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003423 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003424 result = L2CAP_CR_PEND;
3425 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003426 }
3427
Linus Torvalds1da177e2005-04-16 15:20:36 -07003428response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003429 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003430 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003431
3432sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003433 rsp.scid = cpu_to_le16(scid);
3434 rsp.dcid = cpu_to_le16(dcid);
3435 rsp.result = cpu_to_le16(result);
3436 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003437 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003438
3439 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3440 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003441 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003442
3443 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3444 conn->info_ident = l2cap_get_ident(conn);
3445
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003446 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003447
3448 l2cap_send_cmd(conn, conn->info_ident,
3449 L2CAP_INFO_REQ, sizeof(info), &info);
3450 }
3451
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003452 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003453 result == L2CAP_CR_SUCCESS) {
3454 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003455 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003456 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003457 l2cap_build_conf_req(chan, buf), buf);
3458 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003459 }
3460
Linus Torvalds1da177e2005-04-16 15:20:36 -07003461 return 0;
3462}
3463
3464static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3465{
3466 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3467 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003468 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003469 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003470 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003471
3472 scid = __le16_to_cpu(rsp->scid);
3473 dcid = __le16_to_cpu(rsp->dcid);
3474 result = __le16_to_cpu(rsp->result);
3475 status = __le16_to_cpu(rsp->status);
3476
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003477 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x",
3478 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003479
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003480 mutex_lock(&conn->chan_lock);
3481
Linus Torvalds1da177e2005-04-16 15:20:36 -07003482 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003483 chan = __l2cap_get_chan_by_scid(conn, scid);
3484 if (!chan) {
3485 err = -EFAULT;
3486 goto unlock;
3487 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003488 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003489 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3490 if (!chan) {
3491 err = -EFAULT;
3492 goto unlock;
3493 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003494 }
3495
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003496 err = 0;
3497
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003498 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003499
Linus Torvalds1da177e2005-04-16 15:20:36 -07003500 switch (result) {
3501 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003502 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003503 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003504 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003505 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003506
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003507 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003508 break;
3509
Linus Torvalds1da177e2005-04-16 15:20:36 -07003510 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003511 l2cap_build_conf_req(chan, req), req);
3512 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003513 break;
3514
3515 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003516 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003517 break;
3518
3519 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003520 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003521 break;
3522 }
3523
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003524 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003525
3526unlock:
3527 mutex_unlock(&conn->chan_lock);
3528
3529 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003530}
3531
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003532static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003533{
3534 /* FCS is enabled only in ERTM or streaming mode, if one or both
3535 * sides request it.
3536 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003537 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003538 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003539 else if (!test_bit(CONF_NO_FCS_RECV, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003540 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003541}
3542
Al Viro88219a02007-07-29 00:17:25 -07003543static 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 -07003544{
3545 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3546 u16 dcid, flags;
3547 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003548 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003549 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003550
3551 dcid = __le16_to_cpu(req->dcid);
3552 flags = __le16_to_cpu(req->flags);
3553
3554 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3555
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003556 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003557 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003558 return -ENOENT;
3559
David S. Miller033b1142011-07-21 13:38:42 -07003560 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003561 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003562
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003563 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003564 rej.scid = cpu_to_le16(chan->scid);
3565 rej.dcid = cpu_to_le16(chan->dcid);
3566
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003567 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
3568 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003569 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003570 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003571
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003572 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003573 len = cmd_len - sizeof(*req);
Dan Rosenberg7ac28812011-06-24 08:38:05 -04003574 if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003575 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003576 l2cap_build_conf_rsp(chan, rsp,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003577 L2CAP_CONF_REJECT, flags), rsp);
3578 goto unlock;
3579 }
3580
3581 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003582 memcpy(chan->conf_req + chan->conf_len, req->data, len);
3583 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003584
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003585 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003586 /* Incomplete config. Send empty response. */
3587 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003588 l2cap_build_conf_rsp(chan, rsp,
Andrei Emeltchenko5325e5b2012-05-23 11:31:22 +03003589 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003590 goto unlock;
3591 }
3592
3593 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003594 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003595 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003596 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003597 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003598 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003599
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003600 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003601 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003602
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003603 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003604 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003605
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003606 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02003607 goto unlock;
3608
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003609 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003610 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003611
Mat Martineau105bdf92012-04-27 16:50:48 -07003612 if (chan->mode == L2CAP_MODE_ERTM ||
3613 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003614 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003615
Mat Martineau3c588192012-04-11 10:48:42 -07003616 if (err < 0)
3617 l2cap_send_disconn_req(chan->conn, chan, -err);
3618 else
3619 l2cap_chan_ready(chan);
3620
Marcel Holtmann876d9482007-10-20 13:35:42 +02003621 goto unlock;
3622 }
3623
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003624 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003625 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003626 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003627 l2cap_build_conf_req(chan, buf), buf);
3628 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003629 }
3630
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003631 /* Got Conf Rsp PENDING from remote side and asume we sent
3632 Conf Rsp PENDING in the code above */
3633 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
3634 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3635
3636 /* check compatibility */
3637
3638 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3639 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3640
3641 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003642 l2cap_build_conf_rsp(chan, rsp,
Andrei Emeltchenko5325e5b2012-05-23 11:31:22 +03003643 L2CAP_CONF_SUCCESS, flags), rsp);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003644 }
3645
Linus Torvalds1da177e2005-04-16 15:20:36 -07003646unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003647 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003648 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003649}
3650
3651static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3652{
3653 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3654 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003655 struct l2cap_chan *chan;
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003656 int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07003657 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003658
3659 scid = __le16_to_cpu(rsp->scid);
3660 flags = __le16_to_cpu(rsp->flags);
3661 result = __le16_to_cpu(rsp->result);
3662
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003663 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
3664 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003665
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003666 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003667 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003668 return 0;
3669
3670 switch (result) {
3671 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003672 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003673 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003674 break;
3675
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003676 case L2CAP_CONF_PENDING:
3677 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
3678
3679 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3680 char buf[64];
3681
3682 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3683 buf, &result);
3684 if (len < 0) {
3685 l2cap_send_disconn_req(conn, chan, ECONNRESET);
3686 goto done;
3687 }
3688
3689 /* check compatibility */
3690
3691 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3692 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3693
3694 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003695 l2cap_build_conf_rsp(chan, buf,
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003696 L2CAP_CONF_SUCCESS, 0x0000), buf);
3697 }
3698 goto done;
3699
Linus Torvalds1da177e2005-04-16 15:20:36 -07003700 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003701 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003702 char req[64];
3703
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003704 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003705 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003706 goto done;
3707 }
3708
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003709 /* throw out any old stored conf requests */
3710 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003711 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3712 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003713 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003714 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003715 goto done;
3716 }
3717
3718 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3719 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003720 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003721 if (result != L2CAP_CONF_SUCCESS)
3722 goto done;
3723 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003724 }
3725
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003726 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003727 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02003728
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003729 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003730 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003731 goto done;
3732 }
3733
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003734 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003735 goto done;
3736
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003737 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003738
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003739 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003740 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003741
Mat Martineau105bdf92012-04-27 16:50:48 -07003742 if (chan->mode == L2CAP_MODE_ERTM ||
3743 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003744 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003745
Mat Martineau3c588192012-04-11 10:48:42 -07003746 if (err < 0)
3747 l2cap_send_disconn_req(chan->conn, chan, -err);
3748 else
3749 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003750 }
3751
3752done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003753 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003754 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003755}
3756
3757static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3758{
3759 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3760 struct l2cap_disconn_rsp rsp;
3761 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003762 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003763 struct sock *sk;
3764
3765 scid = __le16_to_cpu(req->scid);
3766 dcid = __le16_to_cpu(req->dcid);
3767
3768 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3769
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003770 mutex_lock(&conn->chan_lock);
3771
3772 chan = __l2cap_get_chan_by_scid(conn, dcid);
3773 if (!chan) {
3774 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003775 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003776 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003777
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003778 l2cap_chan_lock(chan);
3779
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003780 sk = chan->sk;
3781
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003782 rsp.dcid = cpu_to_le16(chan->scid);
3783 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003784 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3785
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003786 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003787 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003788 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003789
Mat Martineau61d6ef32012-04-27 16:50:50 -07003790 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003791 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003792
3793 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003794
Gustavo Padovan80b98022012-05-27 22:27:51 -03003795 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003796 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003797
3798 mutex_unlock(&conn->chan_lock);
3799
Linus Torvalds1da177e2005-04-16 15:20:36 -07003800 return 0;
3801}
3802
3803static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3804{
3805 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3806 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003807 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003808
3809 scid = __le16_to_cpu(rsp->scid);
3810 dcid = __le16_to_cpu(rsp->dcid);
3811
3812 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3813
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003814 mutex_lock(&conn->chan_lock);
3815
3816 chan = __l2cap_get_chan_by_scid(conn, scid);
3817 if (!chan) {
3818 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003819 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003820 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003821
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003822 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003823
Mat Martineau61d6ef32012-04-27 16:50:50 -07003824 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003825 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003826
3827 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003828
Gustavo Padovan80b98022012-05-27 22:27:51 -03003829 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003830 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003831
3832 mutex_unlock(&conn->chan_lock);
3833
Linus Torvalds1da177e2005-04-16 15:20:36 -07003834 return 0;
3835}
3836
3837static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3838{
3839 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003840 u16 type;
3841
3842 type = __le16_to_cpu(req->type);
3843
3844 BT_DBG("type 0x%4.4x", type);
3845
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003846 if (type == L2CAP_IT_FEAT_MASK) {
3847 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003848 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003849 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003850 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
3851 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03003852 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003853 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3854 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003855 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003856 feat_mask |= L2CAP_FEAT_EXT_FLOW
3857 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003858
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003859 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003860 l2cap_send_cmd(conn, cmd->ident,
3861 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003862 } else if (type == L2CAP_IT_FIXED_CHAN) {
3863 u8 buf[12];
3864 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07003865
3866 if (enable_hs)
3867 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
3868 else
3869 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
3870
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003871 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3872 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03003873 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003874 l2cap_send_cmd(conn, cmd->ident,
3875 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003876 } else {
3877 struct l2cap_info_rsp rsp;
3878 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003879 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003880 l2cap_send_cmd(conn, cmd->ident,
3881 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3882 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003883
3884 return 0;
3885}
3886
3887static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3888{
3889 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3890 u16 type, result;
3891
3892 type = __le16_to_cpu(rsp->type);
3893 result = __le16_to_cpu(rsp->result);
3894
3895 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3896
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02003897 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
3898 if (cmd->ident != conn->info_ident ||
3899 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
3900 return 0;
3901
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003902 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003903
Ville Tervoadb08ed2010-08-04 09:43:33 +03003904 if (result != L2CAP_IR_SUCCESS) {
3905 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3906 conn->info_ident = 0;
3907
3908 l2cap_conn_start(conn);
3909
3910 return 0;
3911 }
3912
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003913 switch (type) {
3914 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07003915 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003916
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003917 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003918 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003919 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003920
3921 conn->info_ident = l2cap_get_ident(conn);
3922
3923 l2cap_send_cmd(conn, conn->info_ident,
3924 L2CAP_INFO_REQ, sizeof(req), &req);
3925 } else {
3926 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3927 conn->info_ident = 0;
3928
3929 l2cap_conn_start(conn);
3930 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003931 break;
3932
3933 case L2CAP_IT_FIXED_CHAN:
3934 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01003935 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003936 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003937
3938 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003939 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003940 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003941
Linus Torvalds1da177e2005-04-16 15:20:36 -07003942 return 0;
3943}
3944
Mat Martineauf94ff6f2011-11-02 16:18:32 -07003945static inline int l2cap_create_channel_req(struct l2cap_conn *conn,
3946 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3947 void *data)
3948{
3949 struct l2cap_create_chan_req *req = data;
3950 struct l2cap_create_chan_rsp rsp;
3951 u16 psm, scid;
3952
3953 if (cmd_len != sizeof(*req))
3954 return -EPROTO;
3955
3956 if (!enable_hs)
3957 return -EINVAL;
3958
3959 psm = le16_to_cpu(req->psm);
3960 scid = le16_to_cpu(req->scid);
3961
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03003962 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 -07003963
3964 /* Placeholder: Always reject */
3965 rsp.dcid = 0;
3966 rsp.scid = cpu_to_le16(scid);
Andrei Emeltchenko8ce0c492012-03-12 12:13:09 +02003967 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
3968 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07003969
3970 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
3971 sizeof(rsp), &rsp);
3972
3973 return 0;
3974}
3975
3976static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn,
3977 struct l2cap_cmd_hdr *cmd, void *data)
3978{
3979 BT_DBG("conn %p", conn);
3980
3981 return l2cap_connect_rsp(conn, cmd, data);
3982}
3983
Mat Martineau8d5a04a2011-11-02 16:18:35 -07003984static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03003985 u16 icid, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07003986{
3987 struct l2cap_move_chan_rsp rsp;
3988
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03003989 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07003990
3991 rsp.icid = cpu_to_le16(icid);
3992 rsp.result = cpu_to_le16(result);
3993
3994 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_RSP, sizeof(rsp), &rsp);
3995}
3996
3997static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03003998 struct l2cap_chan *chan,
3999 u16 icid, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004000{
4001 struct l2cap_move_chan_cfm cfm;
4002 u8 ident;
4003
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004004 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004005
4006 ident = l2cap_get_ident(conn);
4007 if (chan)
4008 chan->ident = ident;
4009
4010 cfm.icid = cpu_to_le16(icid);
4011 cfm.result = cpu_to_le16(result);
4012
4013 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM, sizeof(cfm), &cfm);
4014}
4015
4016static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004017 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004018{
4019 struct l2cap_move_chan_cfm_rsp rsp;
4020
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004021 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004022
4023 rsp.icid = cpu_to_le16(icid);
4024 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4025}
4026
4027static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004028 struct l2cap_cmd_hdr *cmd,
4029 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004030{
4031 struct l2cap_move_chan_req *req = data;
4032 u16 icid = 0;
4033 u16 result = L2CAP_MR_NOT_ALLOWED;
4034
4035 if (cmd_len != sizeof(*req))
4036 return -EPROTO;
4037
4038 icid = le16_to_cpu(req->icid);
4039
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004040 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004041
4042 if (!enable_hs)
4043 return -EINVAL;
4044
4045 /* Placeholder: Always refuse */
4046 l2cap_send_move_chan_rsp(conn, cmd->ident, icid, result);
4047
4048 return 0;
4049}
4050
4051static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004052 struct l2cap_cmd_hdr *cmd,
4053 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004054{
4055 struct l2cap_move_chan_rsp *rsp = data;
4056 u16 icid, result;
4057
4058 if (cmd_len != sizeof(*rsp))
4059 return -EPROTO;
4060
4061 icid = le16_to_cpu(rsp->icid);
4062 result = le16_to_cpu(rsp->result);
4063
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004064 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004065
4066 /* Placeholder: Always unconfirmed */
4067 l2cap_send_move_chan_cfm(conn, NULL, icid, L2CAP_MC_UNCONFIRMED);
4068
4069 return 0;
4070}
4071
4072static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004073 struct l2cap_cmd_hdr *cmd,
4074 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004075{
4076 struct l2cap_move_chan_cfm *cfm = data;
4077 u16 icid, result;
4078
4079 if (cmd_len != sizeof(*cfm))
4080 return -EPROTO;
4081
4082 icid = le16_to_cpu(cfm->icid);
4083 result = le16_to_cpu(cfm->result);
4084
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004085 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004086
4087 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4088
4089 return 0;
4090}
4091
4092static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004093 struct l2cap_cmd_hdr *cmd,
4094 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004095{
4096 struct l2cap_move_chan_cfm_rsp *rsp = data;
4097 u16 icid;
4098
4099 if (cmd_len != sizeof(*rsp))
4100 return -EPROTO;
4101
4102 icid = le16_to_cpu(rsp->icid);
4103
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004104 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004105
4106 return 0;
4107}
4108
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004109static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Claudio Takahaside731152011-02-11 19:28:55 -02004110 u16 to_multiplier)
4111{
4112 u16 max_latency;
4113
4114 if (min > max || min < 6 || max > 3200)
4115 return -EINVAL;
4116
4117 if (to_multiplier < 10 || to_multiplier > 3200)
4118 return -EINVAL;
4119
4120 if (max >= to_multiplier * 8)
4121 return -EINVAL;
4122
4123 max_latency = (to_multiplier * 8 / max) - 1;
4124 if (latency > 499 || latency > max_latency)
4125 return -EINVAL;
4126
4127 return 0;
4128}
4129
4130static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
4131 struct l2cap_cmd_hdr *cmd, u8 *data)
4132{
4133 struct hci_conn *hcon = conn->hcon;
4134 struct l2cap_conn_param_update_req *req;
4135 struct l2cap_conn_param_update_rsp rsp;
4136 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004137 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02004138
4139 if (!(hcon->link_mode & HCI_LM_MASTER))
4140 return -EINVAL;
4141
4142 cmd_len = __le16_to_cpu(cmd->len);
4143 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
4144 return -EPROTO;
4145
4146 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004147 min = __le16_to_cpu(req->min);
4148 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02004149 latency = __le16_to_cpu(req->latency);
4150 to_multiplier = __le16_to_cpu(req->to_multiplier);
4151
4152 BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
4153 min, max, latency, to_multiplier);
4154
4155 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004156
4157 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
4158 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004159 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004160 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004161 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004162
4163 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
4164 sizeof(rsp), &rsp);
4165
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004166 if (!err)
4167 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
4168
Claudio Takahaside731152011-02-11 19:28:55 -02004169 return 0;
4170}
4171
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004172static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
4173 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
4174{
4175 int err = 0;
4176
4177 switch (cmd->code) {
4178 case L2CAP_COMMAND_REJ:
4179 l2cap_command_rej(conn, cmd, data);
4180 break;
4181
4182 case L2CAP_CONN_REQ:
4183 err = l2cap_connect_req(conn, cmd, data);
4184 break;
4185
4186 case L2CAP_CONN_RSP:
4187 err = l2cap_connect_rsp(conn, cmd, data);
4188 break;
4189
4190 case L2CAP_CONF_REQ:
4191 err = l2cap_config_req(conn, cmd, cmd_len, data);
4192 break;
4193
4194 case L2CAP_CONF_RSP:
4195 err = l2cap_config_rsp(conn, cmd, data);
4196 break;
4197
4198 case L2CAP_DISCONN_REQ:
4199 err = l2cap_disconnect_req(conn, cmd, data);
4200 break;
4201
4202 case L2CAP_DISCONN_RSP:
4203 err = l2cap_disconnect_rsp(conn, cmd, data);
4204 break;
4205
4206 case L2CAP_ECHO_REQ:
4207 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
4208 break;
4209
4210 case L2CAP_ECHO_RSP:
4211 break;
4212
4213 case L2CAP_INFO_REQ:
4214 err = l2cap_information_req(conn, cmd, data);
4215 break;
4216
4217 case L2CAP_INFO_RSP:
4218 err = l2cap_information_rsp(conn, cmd, data);
4219 break;
4220
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004221 case L2CAP_CREATE_CHAN_REQ:
4222 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
4223 break;
4224
4225 case L2CAP_CREATE_CHAN_RSP:
4226 err = l2cap_create_channel_rsp(conn, cmd, data);
4227 break;
4228
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004229 case L2CAP_MOVE_CHAN_REQ:
4230 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
4231 break;
4232
4233 case L2CAP_MOVE_CHAN_RSP:
4234 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
4235 break;
4236
4237 case L2CAP_MOVE_CHAN_CFM:
4238 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
4239 break;
4240
4241 case L2CAP_MOVE_CHAN_CFM_RSP:
4242 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
4243 break;
4244
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004245 default:
4246 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
4247 err = -EINVAL;
4248 break;
4249 }
4250
4251 return err;
4252}
4253
4254static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
4255 struct l2cap_cmd_hdr *cmd, u8 *data)
4256{
4257 switch (cmd->code) {
4258 case L2CAP_COMMAND_REJ:
4259 return 0;
4260
4261 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02004262 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004263
4264 case L2CAP_CONN_PARAM_UPDATE_RSP:
4265 return 0;
4266
4267 default:
4268 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
4269 return -EINVAL;
4270 }
4271}
4272
4273static inline void l2cap_sig_channel(struct l2cap_conn *conn,
4274 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004275{
4276 u8 *data = skb->data;
4277 int len = skb->len;
4278 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004279 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004280
4281 l2cap_raw_recv(conn, skb);
4282
4283 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07004284 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004285 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
4286 data += L2CAP_CMD_HDR_SIZE;
4287 len -= L2CAP_CMD_HDR_SIZE;
4288
Al Viro88219a02007-07-29 00:17:25 -07004289 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004290
Al Viro88219a02007-07-29 00:17:25 -07004291 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 -07004292
Al Viro88219a02007-07-29 00:17:25 -07004293 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004294 BT_DBG("corrupted command");
4295 break;
4296 }
4297
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004298 if (conn->hcon->type == LE_LINK)
4299 err = l2cap_le_sig_cmd(conn, &cmd, data);
4300 else
4301 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004302
4303 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004304 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03004305
4306 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004307
4308 /* FIXME: Map err to a valid reason */
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004309 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004310 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
4311 }
4312
Al Viro88219a02007-07-29 00:17:25 -07004313 data += cmd_len;
4314 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004315 }
4316
4317 kfree_skb(skb);
4318}
4319
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004320static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004321{
4322 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03004323 int hdr_size;
4324
4325 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
4326 hdr_size = L2CAP_EXT_HDR_SIZE;
4327 else
4328 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004329
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004330 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004331 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004332 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
4333 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
4334
4335 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03004336 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004337 }
4338 return 0;
4339}
4340
Mat Martineau6ea00482012-05-17 20:53:52 -07004341static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004342{
Mat Martineaue31f7632012-05-17 20:53:41 -07004343 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004344
Mat Martineaue31f7632012-05-17 20:53:41 -07004345 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004346
Mat Martineaue31f7632012-05-17 20:53:41 -07004347 memset(&control, 0, sizeof(control));
4348 control.sframe = 1;
4349 control.final = 1;
4350 control.reqseq = chan->buffer_seq;
4351 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004352
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004353 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07004354 control.super = L2CAP_SUPER_RNR;
4355 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004356 }
4357
Mat Martineaue31f7632012-05-17 20:53:41 -07004358 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
4359 chan->unacked_frames > 0)
4360 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004361
Mat Martineaue31f7632012-05-17 20:53:41 -07004362 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03004363 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004364
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004365 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07004366 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
4367 /* F-bit wasn't sent in an s-frame or i-frame yet, so
4368 * send it now.
4369 */
4370 control.super = L2CAP_SUPER_RR;
4371 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004372 }
4373}
4374
Mat Martineau84084a32011-07-22 14:54:00 -07004375static void append_skb_frag(struct sk_buff *skb,
4376 struct sk_buff *new_frag, struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004377{
Mat Martineau84084a32011-07-22 14:54:00 -07004378 /* skb->len reflects data in skb as well as all fragments
4379 * skb->data_len reflects only data in fragments
4380 */
4381 if (!skb_has_frag_list(skb))
4382 skb_shinfo(skb)->frag_list = new_frag;
4383
4384 new_frag->next = NULL;
4385
4386 (*last_frag)->next = new_frag;
4387 *last_frag = new_frag;
4388
4389 skb->len += new_frag->len;
4390 skb->data_len += new_frag->len;
4391 skb->truesize += new_frag->truesize;
4392}
4393
Mat Martineau4b51dae92012-05-17 20:53:37 -07004394static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
4395 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07004396{
4397 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004398
Mat Martineau4b51dae92012-05-17 20:53:37 -07004399 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004400 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07004401 if (chan->sdu)
4402 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004403
Gustavo Padovan80b98022012-05-27 22:27:51 -03004404 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07004405 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004406
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004407 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07004408 if (chan->sdu)
4409 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004410
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004411 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004412 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004413
Mat Martineau84084a32011-07-22 14:54:00 -07004414 if (chan->sdu_len > chan->imtu) {
4415 err = -EMSGSIZE;
4416 break;
4417 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004418
Mat Martineau84084a32011-07-22 14:54:00 -07004419 if (skb->len >= chan->sdu_len)
4420 break;
4421
4422 chan->sdu = skb;
4423 chan->sdu_last_frag = skb;
4424
4425 skb = NULL;
4426 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004427 break;
4428
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004429 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004430 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004431 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004432
Mat Martineau84084a32011-07-22 14:54:00 -07004433 append_skb_frag(chan->sdu, skb,
4434 &chan->sdu_last_frag);
4435 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004436
Mat Martineau84084a32011-07-22 14:54:00 -07004437 if (chan->sdu->len >= chan->sdu_len)
4438 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004439
Mat Martineau84084a32011-07-22 14:54:00 -07004440 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004441 break;
4442
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004443 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004444 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004445 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004446
Mat Martineau84084a32011-07-22 14:54:00 -07004447 append_skb_frag(chan->sdu, skb,
4448 &chan->sdu_last_frag);
4449 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004450
Mat Martineau84084a32011-07-22 14:54:00 -07004451 if (chan->sdu->len != chan->sdu_len)
4452 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004453
Gustavo Padovan80b98022012-05-27 22:27:51 -03004454 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004455
Mat Martineau84084a32011-07-22 14:54:00 -07004456 if (!err) {
4457 /* Reassembly complete */
4458 chan->sdu = NULL;
4459 chan->sdu_last_frag = NULL;
4460 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004461 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004462 break;
4463 }
4464
Mat Martineau84084a32011-07-22 14:54:00 -07004465 if (err) {
4466 kfree_skb(skb);
4467 kfree_skb(chan->sdu);
4468 chan->sdu = NULL;
4469 chan->sdu_last_frag = NULL;
4470 chan->sdu_len = 0;
4471 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004472
Mat Martineau84084a32011-07-22 14:54:00 -07004473 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004474}
4475
Mat Martineaue3281402011-07-07 09:39:02 -07004476void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03004477{
Mat Martineau61aa4f52012-05-17 20:53:40 -07004478 u8 event;
4479
4480 if (chan->mode != L2CAP_MODE_ERTM)
4481 return;
4482
4483 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03004484 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004485}
4486
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004487static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
4488{
Mat Martineau63838722012-05-17 20:53:45 -07004489 int err = 0;
4490 /* Pass sequential frames to l2cap_reassemble_sdu()
4491 * until a gap is encountered.
4492 */
4493
4494 BT_DBG("chan %p", chan);
4495
4496 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4497 struct sk_buff *skb;
4498 BT_DBG("Searching for skb with txseq %d (queue len %d)",
4499 chan->buffer_seq, skb_queue_len(&chan->srej_q));
4500
4501 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
4502
4503 if (!skb)
4504 break;
4505
4506 skb_unlink(skb, &chan->srej_q);
4507 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
4508 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
4509 if (err)
4510 break;
4511 }
4512
4513 if (skb_queue_empty(&chan->srej_q)) {
4514 chan->rx_state = L2CAP_RX_STATE_RECV;
4515 l2cap_send_ack(chan);
4516 }
4517
4518 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004519}
4520
4521static void l2cap_handle_srej(struct l2cap_chan *chan,
4522 struct l2cap_ctrl *control)
4523{
Mat Martineauf80842a2012-05-17 20:53:46 -07004524 struct sk_buff *skb;
4525
4526 BT_DBG("chan %p, control %p", chan, control);
4527
4528 if (control->reqseq == chan->next_tx_seq) {
4529 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4530 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4531 return;
4532 }
4533
4534 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4535
4536 if (skb == NULL) {
4537 BT_DBG("Seq %d not available for retransmission",
4538 control->reqseq);
4539 return;
4540 }
4541
4542 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
4543 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4544 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4545 return;
4546 }
4547
4548 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4549
4550 if (control->poll) {
4551 l2cap_pass_to_tx(chan, control);
4552
4553 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4554 l2cap_retransmit(chan, control);
4555 l2cap_ertm_send(chan);
4556
4557 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4558 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4559 chan->srej_save_reqseq = control->reqseq;
4560 }
4561 } else {
4562 l2cap_pass_to_tx_fbit(chan, control);
4563
4564 if (control->final) {
4565 if (chan->srej_save_reqseq != control->reqseq ||
4566 !test_and_clear_bit(CONN_SREJ_ACT,
4567 &chan->conn_state))
4568 l2cap_retransmit(chan, control);
4569 } else {
4570 l2cap_retransmit(chan, control);
4571 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4572 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4573 chan->srej_save_reqseq = control->reqseq;
4574 }
4575 }
4576 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004577}
4578
4579static void l2cap_handle_rej(struct l2cap_chan *chan,
4580 struct l2cap_ctrl *control)
4581{
Mat Martineaufcd289d2012-05-17 20:53:47 -07004582 struct sk_buff *skb;
4583
4584 BT_DBG("chan %p, control %p", chan, control);
4585
4586 if (control->reqseq == chan->next_tx_seq) {
4587 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4588 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4589 return;
4590 }
4591
4592 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4593
4594 if (chan->max_tx && skb &&
4595 bt_cb(skb)->control.retries >= chan->max_tx) {
4596 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4597 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4598 return;
4599 }
4600
4601 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4602
4603 l2cap_pass_to_tx(chan, control);
4604
4605 if (control->final) {
4606 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
4607 l2cap_retransmit_all(chan, control);
4608 } else {
4609 l2cap_retransmit_all(chan, control);
4610 l2cap_ertm_send(chan);
4611 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
4612 set_bit(CONN_REJ_ACT, &chan->conn_state);
4613 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004614}
4615
Mat Martineau4b51dae92012-05-17 20:53:37 -07004616static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
4617{
4618 BT_DBG("chan %p, txseq %d", chan, txseq);
4619
4620 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
4621 chan->expected_tx_seq);
4622
4623 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
4624 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4625 chan->tx_win) {
4626 /* See notes below regarding "double poll" and
4627 * invalid packets.
4628 */
4629 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4630 BT_DBG("Invalid/Ignore - after SREJ");
4631 return L2CAP_TXSEQ_INVALID_IGNORE;
4632 } else {
4633 BT_DBG("Invalid - in window after SREJ sent");
4634 return L2CAP_TXSEQ_INVALID;
4635 }
4636 }
4637
4638 if (chan->srej_list.head == txseq) {
4639 BT_DBG("Expected SREJ");
4640 return L2CAP_TXSEQ_EXPECTED_SREJ;
4641 }
4642
4643 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
4644 BT_DBG("Duplicate SREJ - txseq already stored");
4645 return L2CAP_TXSEQ_DUPLICATE_SREJ;
4646 }
4647
4648 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
4649 BT_DBG("Unexpected SREJ - not requested");
4650 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
4651 }
4652 }
4653
4654 if (chan->expected_tx_seq == txseq) {
4655 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4656 chan->tx_win) {
4657 BT_DBG("Invalid - txseq outside tx window");
4658 return L2CAP_TXSEQ_INVALID;
4659 } else {
4660 BT_DBG("Expected");
4661 return L2CAP_TXSEQ_EXPECTED;
4662 }
4663 }
4664
4665 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
4666 __seq_offset(chan, chan->expected_tx_seq,
4667 chan->last_acked_seq)){
4668 BT_DBG("Duplicate - expected_tx_seq later than txseq");
4669 return L2CAP_TXSEQ_DUPLICATE;
4670 }
4671
4672 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
4673 /* A source of invalid packets is a "double poll" condition,
4674 * where delays cause us to send multiple poll packets. If
4675 * the remote stack receives and processes both polls,
4676 * sequence numbers can wrap around in such a way that a
4677 * resent frame has a sequence number that looks like new data
4678 * with a sequence gap. This would trigger an erroneous SREJ
4679 * request.
4680 *
4681 * Fortunately, this is impossible with a tx window that's
4682 * less than half of the maximum sequence number, which allows
4683 * invalid frames to be safely ignored.
4684 *
4685 * With tx window sizes greater than half of the tx window
4686 * maximum, the frame is invalid and cannot be ignored. This
4687 * causes a disconnect.
4688 */
4689
4690 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4691 BT_DBG("Invalid/Ignore - txseq outside tx window");
4692 return L2CAP_TXSEQ_INVALID_IGNORE;
4693 } else {
4694 BT_DBG("Invalid - txseq outside tx window");
4695 return L2CAP_TXSEQ_INVALID;
4696 }
4697 } else {
4698 BT_DBG("Unexpected - txseq indicates missing frames");
4699 return L2CAP_TXSEQ_UNEXPECTED;
4700 }
4701}
4702
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004703static int l2cap_rx_state_recv(struct l2cap_chan *chan,
4704 struct l2cap_ctrl *control,
4705 struct sk_buff *skb, u8 event)
4706{
4707 int err = 0;
4708 bool skb_in_use = 0;
4709
4710 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4711 event);
4712
4713 switch (event) {
4714 case L2CAP_EV_RECV_IFRAME:
4715 switch (l2cap_classify_txseq(chan, control->txseq)) {
4716 case L2CAP_TXSEQ_EXPECTED:
4717 l2cap_pass_to_tx(chan, control);
4718
4719 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4720 BT_DBG("Busy, discarding expected seq %d",
4721 control->txseq);
4722 break;
4723 }
4724
4725 chan->expected_tx_seq = __next_seq(chan,
4726 control->txseq);
4727
4728 chan->buffer_seq = chan->expected_tx_seq;
4729 skb_in_use = 1;
4730
4731 err = l2cap_reassemble_sdu(chan, skb, control);
4732 if (err)
4733 break;
4734
4735 if (control->final) {
4736 if (!test_and_clear_bit(CONN_REJ_ACT,
4737 &chan->conn_state)) {
4738 control->final = 0;
4739 l2cap_retransmit_all(chan, control);
4740 l2cap_ertm_send(chan);
4741 }
4742 }
4743
4744 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
4745 l2cap_send_ack(chan);
4746 break;
4747 case L2CAP_TXSEQ_UNEXPECTED:
4748 l2cap_pass_to_tx(chan, control);
4749
4750 /* Can't issue SREJ frames in the local busy state.
4751 * Drop this frame, it will be seen as missing
4752 * when local busy is exited.
4753 */
4754 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4755 BT_DBG("Busy, discarding unexpected seq %d",
4756 control->txseq);
4757 break;
4758 }
4759
4760 /* There was a gap in the sequence, so an SREJ
4761 * must be sent for each missing frame. The
4762 * current frame is stored for later use.
4763 */
4764 skb_queue_tail(&chan->srej_q, skb);
4765 skb_in_use = 1;
4766 BT_DBG("Queued %p (queue len %d)", skb,
4767 skb_queue_len(&chan->srej_q));
4768
4769 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
4770 l2cap_seq_list_clear(&chan->srej_list);
4771 l2cap_send_srej(chan, control->txseq);
4772
4773 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
4774 break;
4775 case L2CAP_TXSEQ_DUPLICATE:
4776 l2cap_pass_to_tx(chan, control);
4777 break;
4778 case L2CAP_TXSEQ_INVALID_IGNORE:
4779 break;
4780 case L2CAP_TXSEQ_INVALID:
4781 default:
4782 l2cap_send_disconn_req(chan->conn, chan,
4783 ECONNRESET);
4784 break;
4785 }
4786 break;
4787 case L2CAP_EV_RECV_RR:
4788 l2cap_pass_to_tx(chan, control);
4789 if (control->final) {
4790 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4791
4792 if (!test_and_clear_bit(CONN_REJ_ACT,
4793 &chan->conn_state)) {
4794 control->final = 0;
4795 l2cap_retransmit_all(chan, control);
4796 }
4797
4798 l2cap_ertm_send(chan);
4799 } else if (control->poll) {
4800 l2cap_send_i_or_rr_or_rnr(chan);
4801 } else {
4802 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4803 &chan->conn_state) &&
4804 chan->unacked_frames)
4805 __set_retrans_timer(chan);
4806
4807 l2cap_ertm_send(chan);
4808 }
4809 break;
4810 case L2CAP_EV_RECV_RNR:
4811 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4812 l2cap_pass_to_tx(chan, control);
4813 if (control && control->poll) {
4814 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4815 l2cap_send_rr_or_rnr(chan, 0);
4816 }
4817 __clear_retrans_timer(chan);
4818 l2cap_seq_list_clear(&chan->retrans_list);
4819 break;
4820 case L2CAP_EV_RECV_REJ:
4821 l2cap_handle_rej(chan, control);
4822 break;
4823 case L2CAP_EV_RECV_SREJ:
4824 l2cap_handle_srej(chan, control);
4825 break;
4826 default:
4827 break;
4828 }
4829
4830 if (skb && !skb_in_use) {
4831 BT_DBG("Freeing %p", skb);
4832 kfree_skb(skb);
4833 }
4834
4835 return err;
4836}
4837
4838static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
4839 struct l2cap_ctrl *control,
4840 struct sk_buff *skb, u8 event)
4841{
4842 int err = 0;
4843 u16 txseq = control->txseq;
4844 bool skb_in_use = 0;
4845
4846 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4847 event);
4848
4849 switch (event) {
4850 case L2CAP_EV_RECV_IFRAME:
4851 switch (l2cap_classify_txseq(chan, txseq)) {
4852 case L2CAP_TXSEQ_EXPECTED:
4853 /* Keep frame for reassembly later */
4854 l2cap_pass_to_tx(chan, control);
4855 skb_queue_tail(&chan->srej_q, skb);
4856 skb_in_use = 1;
4857 BT_DBG("Queued %p (queue len %d)", skb,
4858 skb_queue_len(&chan->srej_q));
4859
4860 chan->expected_tx_seq = __next_seq(chan, txseq);
4861 break;
4862 case L2CAP_TXSEQ_EXPECTED_SREJ:
4863 l2cap_seq_list_pop(&chan->srej_list);
4864
4865 l2cap_pass_to_tx(chan, control);
4866 skb_queue_tail(&chan->srej_q, skb);
4867 skb_in_use = 1;
4868 BT_DBG("Queued %p (queue len %d)", skb,
4869 skb_queue_len(&chan->srej_q));
4870
4871 err = l2cap_rx_queued_iframes(chan);
4872 if (err)
4873 break;
4874
4875 break;
4876 case L2CAP_TXSEQ_UNEXPECTED:
4877 /* Got a frame that can't be reassembled yet.
4878 * Save it for later, and send SREJs to cover
4879 * the missing frames.
4880 */
4881 skb_queue_tail(&chan->srej_q, skb);
4882 skb_in_use = 1;
4883 BT_DBG("Queued %p (queue len %d)", skb,
4884 skb_queue_len(&chan->srej_q));
4885
4886 l2cap_pass_to_tx(chan, control);
4887 l2cap_send_srej(chan, control->txseq);
4888 break;
4889 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
4890 /* This frame was requested with an SREJ, but
4891 * some expected retransmitted frames are
4892 * missing. Request retransmission of missing
4893 * SREJ'd frames.
4894 */
4895 skb_queue_tail(&chan->srej_q, skb);
4896 skb_in_use = 1;
4897 BT_DBG("Queued %p (queue len %d)", skb,
4898 skb_queue_len(&chan->srej_q));
4899
4900 l2cap_pass_to_tx(chan, control);
4901 l2cap_send_srej_list(chan, control->txseq);
4902 break;
4903 case L2CAP_TXSEQ_DUPLICATE_SREJ:
4904 /* We've already queued this frame. Drop this copy. */
4905 l2cap_pass_to_tx(chan, control);
4906 break;
4907 case L2CAP_TXSEQ_DUPLICATE:
4908 /* Expecting a later sequence number, so this frame
4909 * was already received. Ignore it completely.
4910 */
4911 break;
4912 case L2CAP_TXSEQ_INVALID_IGNORE:
4913 break;
4914 case L2CAP_TXSEQ_INVALID:
4915 default:
4916 l2cap_send_disconn_req(chan->conn, chan,
4917 ECONNRESET);
4918 break;
4919 }
4920 break;
4921 case L2CAP_EV_RECV_RR:
4922 l2cap_pass_to_tx(chan, control);
4923 if (control->final) {
4924 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4925
4926 if (!test_and_clear_bit(CONN_REJ_ACT,
4927 &chan->conn_state)) {
4928 control->final = 0;
4929 l2cap_retransmit_all(chan, control);
4930 }
4931
4932 l2cap_ertm_send(chan);
4933 } else if (control->poll) {
4934 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4935 &chan->conn_state) &&
4936 chan->unacked_frames) {
4937 __set_retrans_timer(chan);
4938 }
4939
4940 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4941 l2cap_send_srej_tail(chan);
4942 } else {
4943 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4944 &chan->conn_state) &&
4945 chan->unacked_frames)
4946 __set_retrans_timer(chan);
4947
4948 l2cap_send_ack(chan);
4949 }
4950 break;
4951 case L2CAP_EV_RECV_RNR:
4952 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4953 l2cap_pass_to_tx(chan, control);
4954 if (control->poll) {
4955 l2cap_send_srej_tail(chan);
4956 } else {
4957 struct l2cap_ctrl rr_control;
4958 memset(&rr_control, 0, sizeof(rr_control));
4959 rr_control.sframe = 1;
4960 rr_control.super = L2CAP_SUPER_RR;
4961 rr_control.reqseq = chan->buffer_seq;
4962 l2cap_send_sframe(chan, &rr_control);
4963 }
4964
4965 break;
4966 case L2CAP_EV_RECV_REJ:
4967 l2cap_handle_rej(chan, control);
4968 break;
4969 case L2CAP_EV_RECV_SREJ:
4970 l2cap_handle_srej(chan, control);
4971 break;
4972 }
4973
4974 if (skb && !skb_in_use) {
4975 BT_DBG("Freeing %p", skb);
4976 kfree_skb(skb);
4977 }
4978
4979 return err;
4980}
4981
4982static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
4983{
4984 /* Make sure reqseq is for a packet that has been sent but not acked */
4985 u16 unacked;
4986
4987 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
4988 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
4989}
4990
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07004991static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
4992 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004993{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004994 int err = 0;
4995
4996 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
4997 control, skb, event, chan->rx_state);
4998
4999 if (__valid_reqseq(chan, control->reqseq)) {
5000 switch (chan->rx_state) {
5001 case L2CAP_RX_STATE_RECV:
5002 err = l2cap_rx_state_recv(chan, control, skb, event);
5003 break;
5004 case L2CAP_RX_STATE_SREJ_SENT:
5005 err = l2cap_rx_state_srej_sent(chan, control, skb,
5006 event);
5007 break;
5008 default:
5009 /* shut it down */
5010 break;
5011 }
5012 } else {
5013 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
5014 control->reqseq, chan->next_tx_seq,
5015 chan->expected_ack_seq);
5016 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
5017 }
5018
5019 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005020}
5021
5022static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5023 struct sk_buff *skb)
5024{
Mat Martineau4b51dae92012-05-17 20:53:37 -07005025 int err = 0;
5026
5027 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
5028 chan->rx_state);
5029
5030 if (l2cap_classify_txseq(chan, control->txseq) ==
5031 L2CAP_TXSEQ_EXPECTED) {
5032 l2cap_pass_to_tx(chan, control);
5033
5034 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
5035 __next_seq(chan, chan->buffer_seq));
5036
5037 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5038
5039 l2cap_reassemble_sdu(chan, skb, control);
5040 } else {
5041 if (chan->sdu) {
5042 kfree_skb(chan->sdu);
5043 chan->sdu = NULL;
5044 }
5045 chan->sdu_last_frag = NULL;
5046 chan->sdu_len = 0;
5047
5048 if (skb) {
5049 BT_DBG("Freeing %p", skb);
5050 kfree_skb(skb);
5051 }
5052 }
5053
5054 chan->last_acked_seq = control->txseq;
5055 chan->expected_tx_seq = __next_seq(chan, control->txseq);
5056
5057 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005058}
5059
5060static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
5061{
5062 struct l2cap_ctrl *control = &bt_cb(skb)->control;
5063 u16 len;
5064 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005065
Mat Martineaub76bbd62012-04-11 10:48:43 -07005066 __unpack_control(chan, skb);
5067
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005068 len = skb->len;
5069
5070 /*
5071 * We can just drop the corrupted I-frame here.
5072 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005073 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005074 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005075 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005076 goto drop;
5077
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005078 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005079 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005080
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005081 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005082 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005083
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005084 if (len > chan->mps) {
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005085 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005086 goto drop;
5087 }
5088
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005089 if (!control->sframe) {
5090 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005091
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005092 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
5093 control->sar, control->reqseq, control->final,
5094 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03005095
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005096 /* Validate F-bit - F=0 always valid, F=1 only
5097 * valid in TX WAIT_F
5098 */
5099 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005100 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005101
5102 if (chan->mode != L2CAP_MODE_STREAMING) {
5103 event = L2CAP_EV_RECV_IFRAME;
5104 err = l2cap_rx(chan, control, skb, event);
5105 } else {
5106 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005107 }
5108
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005109 if (err)
5110 l2cap_send_disconn_req(chan->conn, chan,
5111 ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005112 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005113 const u8 rx_func_to_event[4] = {
5114 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
5115 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
5116 };
5117
5118 /* Only I-frames are expected in streaming mode */
5119 if (chan->mode == L2CAP_MODE_STREAMING)
5120 goto drop;
5121
5122 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
5123 control->reqseq, control->final, control->poll,
5124 control->super);
5125
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005126 if (len != 0) {
5127 BT_ERR("%d", len);
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005128 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005129 goto drop;
5130 }
5131
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005132 /* Validate F and P bits */
5133 if (control->final && (control->poll ||
5134 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
5135 goto drop;
5136
5137 event = rx_func_to_event[control->super];
5138 if (l2cap_rx(chan, control, skb, event))
5139 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005140 }
5141
5142 return 0;
5143
5144drop:
5145 kfree_skb(skb);
5146 return 0;
5147}
5148
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005149static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
5150 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005151{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005152 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005153
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03005154 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005155 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005156 if (cid == L2CAP_CID_A2MP) {
5157 chan = a2mp_channel_create(conn, skb);
5158 if (!chan) {
5159 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005160 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005161 }
5162
5163 l2cap_chan_lock(chan);
5164 } else {
5165 BT_DBG("unknown cid 0x%4.4x", cid);
5166 /* Drop packet and return */
5167 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005168 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005169 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005170 }
5171
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03005172 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005173
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005174 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005175 goto drop;
5176
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005177 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005178 case L2CAP_MODE_BASIC:
5179 /* If socket recv buffers overflows we drop data here
5180 * which is *bad* because L2CAP has to be reliable.
5181 * But we don't have any other choice. L2CAP doesn't
5182 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005183
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005184 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005185 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005186
Gustavo Padovan80b98022012-05-27 22:27:51 -03005187 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005188 goto done;
5189 break;
5190
5191 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005192 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005193 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005194 goto done;
5195
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005196 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005197 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005198 break;
5199 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005200
5201drop:
5202 kfree_skb(skb);
5203
5204done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005205 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005206}
5207
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03005208static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
5209 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005210{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005211 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005212
Ido Yarivc2287682012-04-20 15:46:07 -03005213 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005214 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005215 goto drop;
5216
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005217 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005218
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005219 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005220 goto drop;
5221
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005222 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005223 goto drop;
5224
Gustavo Padovan80b98022012-05-27 22:27:51 -03005225 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03005226 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005227
5228drop:
5229 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005230}
5231
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03005232static void l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
5233 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005234{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005235 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005236
Ido Yarivc2287682012-04-20 15:46:07 -03005237 chan = l2cap_global_chan_by_scid(0, cid, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005238 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005239 goto drop;
5240
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005241 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005242
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005243 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005244 goto drop;
5245
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005246 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005247 goto drop;
5248
Gustavo Padovan80b98022012-05-27 22:27:51 -03005249 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03005250 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005251
5252drop:
5253 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005254}
5255
Linus Torvalds1da177e2005-04-16 15:20:36 -07005256static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
5257{
5258 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07005259 u16 cid, len;
5260 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005261
5262 skb_pull(skb, L2CAP_HDR_SIZE);
5263 cid = __le16_to_cpu(lh->cid);
5264 len = __le16_to_cpu(lh->len);
5265
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005266 if (len != skb->len) {
5267 kfree_skb(skb);
5268 return;
5269 }
5270
Linus Torvalds1da177e2005-04-16 15:20:36 -07005271 BT_DBG("len %d, cid 0x%4.4x", len, cid);
5272
5273 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005274 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005275 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005276 l2cap_sig_channel(conn, skb);
5277 break;
5278
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005279 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02005280 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03005281 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005282 l2cap_conless_channel(conn, psm, skb);
5283 break;
5284
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005285 case L2CAP_CID_LE_DATA:
5286 l2cap_att_channel(conn, cid, skb);
5287 break;
5288
Anderson Brigliab501d6a2011-06-07 18:46:31 -03005289 case L2CAP_CID_SMP:
5290 if (smp_sig_channel(conn, skb))
5291 l2cap_conn_del(conn->hcon, EACCES);
5292 break;
5293
Linus Torvalds1da177e2005-04-16 15:20:36 -07005294 default:
5295 l2cap_data_channel(conn, cid, skb);
5296 break;
5297 }
5298}
5299
5300/* ---- L2CAP interface with lower layer (HCI) ---- */
5301
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005302int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005303{
5304 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005305 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005306
Linus Torvalds1da177e2005-04-16 15:20:36 -07005307 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
5308
5309 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005310 read_lock(&chan_list_lock);
5311 list_for_each_entry(c, &chan_list, global_l) {
5312 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005313
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005314 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005315 continue;
5316
5317 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005318 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005319 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005320 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005321 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005322 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
5323 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005324 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005325 lm2 |= HCI_LM_MASTER;
5326 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005327 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005328 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005329
5330 return exact ? lm1 : lm2;
5331}
5332
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005333int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005334{
Marcel Holtmann01394182006-07-03 10:02:46 +02005335 struct l2cap_conn *conn;
5336
Linus Torvalds1da177e2005-04-16 15:20:36 -07005337 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
5338
Linus Torvalds1da177e2005-04-16 15:20:36 -07005339 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005340 conn = l2cap_conn_add(hcon, status);
5341 if (conn)
5342 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02005343 } else
Joe Perchese1750722011-06-29 18:18:29 -07005344 l2cap_conn_del(hcon, bt_to_errno(status));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005345
5346 return 0;
5347}
5348
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005349int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01005350{
5351 struct l2cap_conn *conn = hcon->l2cap_data;
5352
5353 BT_DBG("hcon %p", hcon);
5354
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005355 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02005356 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01005357 return conn->disc_reason;
5358}
5359
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005360int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005361{
5362 BT_DBG("hcon %p reason %d", hcon, reason);
5363
Joe Perchese1750722011-06-29 18:18:29 -07005364 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005365 return 0;
5366}
5367
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005368static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005369{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03005370 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01005371 return;
5372
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005373 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005374 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005375 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005376 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03005377 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005378 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005379 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03005380 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005381 }
5382}
5383
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005384int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005385{
Marcel Holtmann40be4922008-07-14 20:13:50 +02005386 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005387 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005388
Marcel Holtmann01394182006-07-03 10:02:46 +02005389 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005390 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02005391
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03005392 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005393
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005394 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05305395 if (!status && encrypt)
5396 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02005397 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005398 }
5399
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005400 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005401
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005402 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005403 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005404
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03005405 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
5406 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005407
5408 if (chan->scid == L2CAP_CID_LE_DATA) {
5409 if (!status && encrypt) {
5410 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02005411 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005412 }
5413
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005414 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005415 continue;
5416 }
5417
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03005418 if (test_bit(CONF_CONNECT_PEND, &chan->conf_state)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005419 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01005420 continue;
5421 }
5422
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005423 if (!status && (chan->state == BT_CONNECTED ||
5424 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03005425 struct sock *sk = chan->sk;
5426
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005427 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03005428 sk->sk_state_change(sk);
5429
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005430 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005431 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02005432 continue;
5433 }
5434
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005435 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005436 if (!status) {
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02005437 l2cap_send_conn_req(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005438 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005439 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005440 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005441 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005442 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005443 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005444 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005445
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005446 lock_sock(sk);
5447
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005448 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005449 if (test_bit(BT_SK_DEFER_SETUP,
5450 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005451 struct sock *parent = bt_sk(sk)->parent;
5452 res = L2CAP_CR_PEND;
5453 stat = L2CAP_CS_AUTHOR_PEND;
Ilia Kolomisnky05e9a2f2011-07-15 18:30:21 +00005454 if (parent)
5455 parent->sk_data_ready(parent, 0);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005456 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005457 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005458 res = L2CAP_CR_SUCCESS;
5459 stat = L2CAP_CS_NO_INFO;
5460 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005461 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005462 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005463 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005464 res = L2CAP_CR_SEC_BLOCK;
5465 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005466 }
5467
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005468 release_sock(sk);
5469
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03005470 rsp.scid = cpu_to_le16(chan->dcid);
5471 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005472 rsp.result = cpu_to_le16(res);
5473 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03005474 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
5475 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07005476
5477 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
5478 res == L2CAP_CR_SUCCESS) {
5479 char buf[128];
5480 set_bit(CONF_REQ_SENT, &chan->conf_state);
5481 l2cap_send_cmd(conn, l2cap_get_ident(conn),
5482 L2CAP_CONF_REQ,
5483 l2cap_build_conf_req(chan, buf),
5484 buf);
5485 chan->num_conf_req++;
5486 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005487 }
5488
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005489 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005490 }
5491
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005492 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005493
Linus Torvalds1da177e2005-04-16 15:20:36 -07005494 return 0;
5495}
5496
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005497int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005498{
5499 struct l2cap_conn *conn = hcon->l2cap_data;
5500
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02005501 if (!conn)
5502 conn = l2cap_conn_add(hcon, 0);
5503
5504 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005505 goto drop;
5506
5507 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
5508
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +02005509 if (!(flags & ACL_CONT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005510 struct l2cap_hdr *hdr;
5511 int len;
5512
5513 if (conn->rx_len) {
5514 BT_ERR("Unexpected start frame (len %d)", skb->len);
5515 kfree_skb(conn->rx_skb);
5516 conn->rx_skb = NULL;
5517 conn->rx_len = 0;
5518 l2cap_conn_unreliable(conn, ECOMM);
5519 }
5520
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03005521 /* Start fragment always begin with Basic L2CAP header */
5522 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005523 BT_ERR("Frame is too short (len %d)", skb->len);
5524 l2cap_conn_unreliable(conn, ECOMM);
5525 goto drop;
5526 }
5527
5528 hdr = (struct l2cap_hdr *) skb->data;
5529 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
5530
5531 if (len == skb->len) {
5532 /* Complete frame received */
5533 l2cap_recv_frame(conn, skb);
5534 return 0;
5535 }
5536
5537 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
5538
5539 if (skb->len > len) {
5540 BT_ERR("Frame is too long (len %d, expected len %d)",
5541 skb->len, len);
5542 l2cap_conn_unreliable(conn, ECOMM);
5543 goto drop;
5544 }
5545
5546 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03005547 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
5548 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005549 goto drop;
5550
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005551 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01005552 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005553 conn->rx_len = len - skb->len;
5554 } else {
5555 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
5556
5557 if (!conn->rx_len) {
5558 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
5559 l2cap_conn_unreliable(conn, ECOMM);
5560 goto drop;
5561 }
5562
5563 if (skb->len > conn->rx_len) {
5564 BT_ERR("Fragment is too long (len %d, expected %d)",
5565 skb->len, conn->rx_len);
5566 kfree_skb(conn->rx_skb);
5567 conn->rx_skb = NULL;
5568 conn->rx_len = 0;
5569 l2cap_conn_unreliable(conn, ECOMM);
5570 goto drop;
5571 }
5572
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005573 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01005574 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005575 conn->rx_len -= skb->len;
5576
5577 if (!conn->rx_len) {
5578 /* Complete frame received */
5579 l2cap_recv_frame(conn, conn->rx_skb);
5580 conn->rx_skb = NULL;
5581 }
5582 }
5583
5584drop:
5585 kfree_skb(skb);
5586 return 0;
5587}
5588
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005589static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005590{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005591 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005592
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005593 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005594
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005595 list_for_each_entry(c, &chan_list, global_l) {
5596 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005597
Gustavo F. Padovan903d3432011-02-10 14:16:06 -02005598 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 +01005599 batostr(&bt_sk(sk)->src),
5600 batostr(&bt_sk(sk)->dst),
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005601 c->state, __le16_to_cpu(c->psm),
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005602 c->scid, c->dcid, c->imtu, c->omtu,
5603 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02005604 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005605
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005606 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005607
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005608 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005609}
5610
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005611static int l2cap_debugfs_open(struct inode *inode, struct file *file)
5612{
5613 return single_open(file, l2cap_debugfs_show, inode->i_private);
5614}
5615
5616static const struct file_operations l2cap_debugfs_fops = {
5617 .open = l2cap_debugfs_open,
5618 .read = seq_read,
5619 .llseek = seq_lseek,
5620 .release = single_release,
5621};
5622
5623static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005624
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005625int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005626{
5627 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005628
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005629 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005630 if (err < 0)
5631 return err;
5632
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005633 if (bt_debugfs) {
5634 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
5635 bt_debugfs, NULL, &l2cap_debugfs_fops);
5636 if (!l2cap_debugfs)
5637 BT_ERR("Failed to create L2CAP debug file");
5638 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005639
Linus Torvalds1da177e2005-04-16 15:20:36 -07005640 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005641}
5642
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005643void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005644{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005645 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005646 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005647}
5648
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03005649module_param(disable_ertm, bool, 0644);
5650MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");