blob: e90dacda1072beac19695f0f2700f11ee98bebb9 [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;
434 chan->sec_level = BT_SECURITY_LOW;
435
436 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
437}
438
Andrei Emeltchenko14a28492012-03-23 16:31:49 +0200439static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200440{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300441 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200442 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200443
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200444 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100445
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300446 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200447
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200448 switch (chan->chan_type) {
449 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300450 if (conn->hcon->type == LE_LINK) {
451 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300452 chan->omtu = L2CAP_DEFAULT_MTU;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300453 chan->scid = L2CAP_CID_LE_DATA;
454 chan->dcid = L2CAP_CID_LE_DATA;
Ville Tervob62f3282011-02-10 22:38:50 -0300455 } else {
456 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300457 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300458 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300459 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200460 break;
461
462 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200463 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300464 chan->scid = L2CAP_CID_CONN_LESS;
465 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300466 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200467 break;
468
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300469 case L2CAP_CHAN_CONN_FIX_A2MP:
470 chan->scid = L2CAP_CID_A2MP;
471 chan->dcid = L2CAP_CID_A2MP;
472 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
473 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
474 break;
475
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200476 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200477 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300478 chan->scid = L2CAP_CID_SIGNALING;
479 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300480 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200481 }
482
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300483 chan->local_id = L2CAP_BESTEFFORT_ID;
484 chan->local_stype = L2CAP_SERV_BESTEFFORT;
485 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
486 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
487 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
488 chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO;
489
Ulisses Furquim371fd832011-12-21 20:02:36 -0200490 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300491
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200492 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200493}
494
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300495void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200496{
497 mutex_lock(&conn->chan_lock);
498 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200499 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200500}
501
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300502void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200503{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300504 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200505
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300506 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200507
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300508 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200509
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900510 if (conn) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300511 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200512 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200513
Ulisses Furquim371fd832011-12-21 20:02:36 -0200514 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300515
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300516 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300517
518 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
519 hci_conn_put(conn->hcon);
Marcel Holtmann01394182006-07-03 10:02:46 +0200520 }
521
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300522 if (chan->ops->teardown)
523 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200524
Mat Martineau28270112012-05-17 21:14:09 -0700525 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300526 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300527
Gustavo Padovanee556f62012-05-18 20:22:38 -0300528 switch(chan->mode) {
529 case L2CAP_MODE_BASIC:
530 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300531
Gustavo Padovanee556f62012-05-18 20:22:38 -0300532 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300533 __clear_retrans_timer(chan);
534 __clear_monitor_timer(chan);
535 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300536
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300537 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300538
Mat Martineau3c588192012-04-11 10:48:42 -0700539 l2cap_seq_list_free(&chan->srej_list);
540 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300541
542 /* fall through */
543
544 case L2CAP_MODE_STREAMING:
545 skb_queue_purge(&chan->tx_q);
546 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300547 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300548
549 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200550}
551
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300552void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300553{
554 struct l2cap_conn *conn = chan->conn;
555 struct sock *sk = chan->sk;
556
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200557 BT_DBG("chan %p state %s sk %p", chan,
558 state_to_string(chan->state), sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300559
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300560 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300561 case BT_LISTEN:
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300562 if (chan->ops->teardown)
563 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300564 break;
565
566 case BT_CONNECTED:
567 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300568 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300569 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300570 __set_chan_timer(chan, sk->sk_sndtimeo);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300571 l2cap_send_disconn_req(conn, chan, reason);
572 } else
573 l2cap_chan_del(chan, reason);
574 break;
575
576 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300577 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300578 conn->hcon->type == ACL_LINK) {
579 struct l2cap_conn_rsp rsp;
580 __u16 result;
581
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300582 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300583 result = L2CAP_CR_SEC_BLOCK;
584 else
585 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300586 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300587
588 rsp.scid = cpu_to_le16(chan->dcid);
589 rsp.dcid = cpu_to_le16(chan->scid);
590 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300591 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300592 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
593 sizeof(rsp), &rsp);
594 }
595
596 l2cap_chan_del(chan, reason);
597 break;
598
599 case BT_CONNECT:
600 case BT_DISCONN:
601 l2cap_chan_del(chan, reason);
602 break;
603
604 default:
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300605 if (chan->ops->teardown)
606 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300607 break;
608 }
609}
610
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300611static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530612{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300613 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300614 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530615 case BT_SECURITY_HIGH:
616 return HCI_AT_DEDICATED_BONDING_MITM;
617 case BT_SECURITY_MEDIUM:
618 return HCI_AT_DEDICATED_BONDING;
619 default:
620 return HCI_AT_NO_BONDING;
621 }
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +0300622 } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300623 if (chan->sec_level == BT_SECURITY_LOW)
624 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530625
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300626 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530627 return HCI_AT_NO_BONDING_MITM;
628 else
629 return HCI_AT_NO_BONDING;
630 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300631 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530632 case BT_SECURITY_HIGH:
633 return HCI_AT_GENERAL_BONDING_MITM;
634 case BT_SECURITY_MEDIUM:
635 return HCI_AT_GENERAL_BONDING;
636 default:
637 return HCI_AT_NO_BONDING;
638 }
639 }
640}
641
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200642/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200643int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200644{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300645 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100646 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200647
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300648 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100649
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300650 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200651}
652
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200653static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200654{
655 u8 id;
656
657 /* Get next available identificator.
658 * 1 - 128 are used by kernel.
659 * 129 - 199 are reserved.
660 * 200 - 254 are used by utilities like l2ping, etc.
661 */
662
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200663 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200664
665 if (++conn->tx_ident > 128)
666 conn->tx_ident = 1;
667
668 id = conn->tx_ident;
669
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200670 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200671
672 return id;
673}
674
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300675static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200676{
677 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200678 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200679
680 BT_DBG("code 0x%2.2x", code);
681
682 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300683 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200684
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200685 if (lmp_no_flush_capable(conn->hcon->hdev))
686 flags = ACL_START_NO_FLUSH;
687 else
688 flags = ACL_START;
689
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700690 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200691 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700692
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200693 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200694}
695
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200696static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
697{
698 struct hci_conn *hcon = chan->conn->hcon;
699 u16 flags;
700
701 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
702 skb->priority);
703
704 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
705 lmp_no_flush_capable(hcon->hdev))
706 flags = ACL_START_NO_FLUSH;
707 else
708 flags = ACL_START;
709
710 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
711 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712}
713
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700714static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
715{
716 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
717 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
718
719 if (enh & L2CAP_CTRL_FRAME_TYPE) {
720 /* S-Frame */
721 control->sframe = 1;
722 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
723 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
724
725 control->sar = 0;
726 control->txseq = 0;
727 } else {
728 /* I-Frame */
729 control->sframe = 0;
730 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
731 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
732
733 control->poll = 0;
734 control->super = 0;
735 }
736}
737
738static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
739{
740 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
741 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
742
743 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
744 /* S-Frame */
745 control->sframe = 1;
746 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
747 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
748
749 control->sar = 0;
750 control->txseq = 0;
751 } else {
752 /* I-Frame */
753 control->sframe = 0;
754 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
755 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
756
757 control->poll = 0;
758 control->super = 0;
759 }
760}
761
762static inline void __unpack_control(struct l2cap_chan *chan,
763 struct sk_buff *skb)
764{
765 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
766 __unpack_extended_control(get_unaligned_le32(skb->data),
767 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700768 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700769 } else {
770 __unpack_enhanced_control(get_unaligned_le16(skb->data),
771 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700772 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700773 }
774}
775
776static u32 __pack_extended_control(struct l2cap_ctrl *control)
777{
778 u32 packed;
779
780 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
781 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
782
783 if (control->sframe) {
784 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
785 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
786 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
787 } else {
788 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
789 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
790 }
791
792 return packed;
793}
794
795static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
796{
797 u16 packed;
798
799 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
800 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
801
802 if (control->sframe) {
803 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
804 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
805 packed |= L2CAP_CTRL_FRAME_TYPE;
806 } else {
807 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
808 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
809 }
810
811 return packed;
812}
813
814static inline void __pack_control(struct l2cap_chan *chan,
815 struct l2cap_ctrl *control,
816 struct sk_buff *skb)
817{
818 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
819 put_unaligned_le32(__pack_extended_control(control),
820 skb->data + L2CAP_HDR_SIZE);
821 } else {
822 put_unaligned_le16(__pack_enhanced_control(control),
823 skb->data + L2CAP_HDR_SIZE);
824 }
825}
826
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300827static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
828{
829 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
830 return L2CAP_EXT_HDR_SIZE;
831 else
832 return L2CAP_ENH_HDR_SIZE;
833}
834
Mat Martineaua67d7f62012-05-17 20:53:35 -0700835static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
836 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300837{
838 struct sk_buff *skb;
839 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300840 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300841
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300842 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300843 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300844
Mat Martineaua67d7f62012-05-17 20:53:35 -0700845 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300846
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300847 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700848 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300849
850 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300851 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300852 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300853
Mat Martineaua67d7f62012-05-17 20:53:35 -0700854 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
855 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
856 else
857 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300858
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300859 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700860 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300861 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300862 }
863
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200864 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700865 return skb;
866}
867
868static void l2cap_send_sframe(struct l2cap_chan *chan,
869 struct l2cap_ctrl *control)
870{
871 struct sk_buff *skb;
872 u32 control_field;
873
874 BT_DBG("chan %p, control %p", chan, control);
875
876 if (!control->sframe)
877 return;
878
879 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
880 !control->poll)
881 control->final = 1;
882
883 if (control->super == L2CAP_SUPER_RR)
884 clear_bit(CONN_RNR_SENT, &chan->conn_state);
885 else if (control->super == L2CAP_SUPER_RNR)
886 set_bit(CONN_RNR_SENT, &chan->conn_state);
887
888 if (control->super != L2CAP_SUPER_SREJ) {
889 chan->last_acked_seq = control->reqseq;
890 __clear_ack_timer(chan);
891 }
892
893 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
894 control->final, control->poll, control->super);
895
896 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
897 control_field = __pack_extended_control(control);
898 else
899 control_field = __pack_enhanced_control(control);
900
901 skb = l2cap_create_sframe_pdu(chan, control_field);
902 if (!IS_ERR(skb))
903 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300904}
905
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700906static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300907{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700908 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300909
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700910 BT_DBG("chan %p, poll %d", chan, poll);
911
912 memset(&control, 0, sizeof(control));
913 control.sframe = 1;
914 control.poll = poll;
915
916 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
917 control.super = L2CAP_SUPER_RNR;
918 else
919 control.super = L2CAP_SUPER_RR;
920
921 control.reqseq = chan->buffer_seq;
922 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300923}
924
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300925static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300926{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -0300927 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300928}
929
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +0200930static void l2cap_send_conn_req(struct l2cap_chan *chan)
931{
932 struct l2cap_conn *conn = chan->conn;
933 struct l2cap_conn_req req;
934
935 req.scid = cpu_to_le16(chan->scid);
936 req.psm = chan->psm;
937
938 chan->ident = l2cap_get_ident(conn);
939
940 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
941
942 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
943}
944
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300945static void l2cap_chan_ready(struct l2cap_chan *chan)
946{
Mat Martineau28270112012-05-17 21:14:09 -0700947 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300948 chan->conf_state = 0;
949 __clear_chan_timer(chan);
950
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -0300951 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300952
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +0300953 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300954}
955
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -0300956static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200957{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300958 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200959
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300960 if (conn->hcon->type == LE_LINK) {
961 l2cap_chan_ready(chan);
962 return;
963 }
964
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200965 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100966 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
967 return;
968
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200969 if (l2cap_chan_check_security(chan) &&
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +0200970 __l2cap_no_conn_pending(chan))
971 l2cap_send_conn_req(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200972 } else {
973 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300974 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200975
976 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
977 conn->info_ident = l2cap_get_ident(conn);
978
Marcel Holtmannba13ccd2012-03-01 14:25:33 -0800979 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200980
981 l2cap_send_cmd(conn, conn->info_ident,
982 L2CAP_INFO_REQ, sizeof(req), &req);
983 }
984}
985
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300986static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
987{
988 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -0300989 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -0300990 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
991
992 switch (mode) {
993 case L2CAP_MODE_ERTM:
994 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
995 case L2CAP_MODE_STREAMING:
996 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
997 default:
998 return 0x00;
999 }
1000}
1001
Gustavo F. Padovan4519de92011-04-28 17:55:53 -03001002static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001003{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001004 struct sock *sk = chan->sk;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001005 struct l2cap_disconn_req req;
1006
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001007 if (!conn)
1008 return;
1009
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001010 if (chan->mode == L2CAP_MODE_ERTM) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001011 __clear_retrans_timer(chan);
1012 __clear_monitor_timer(chan);
1013 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001014 }
1015
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001016 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1017 __l2cap_state_change(chan, BT_DISCONN);
1018 return;
1019 }
1020
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001021 req.dcid = cpu_to_le16(chan->dcid);
1022 req.scid = cpu_to_le16(chan->scid);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001023 l2cap_send_cmd(conn, l2cap_get_ident(conn),
1024 L2CAP_DISCONN_REQ, sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001025
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001026 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001027 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001028 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001029 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001030}
1031
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001033static void l2cap_conn_start(struct l2cap_conn *conn)
1034{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001035 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001036
1037 BT_DBG("conn %p", conn);
1038
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001039 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001040
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001041 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001042 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001043
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001044 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001045
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001046 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001047 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001048 continue;
1049 }
1050
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001051 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001052 if (!l2cap_chan_check_security(chan) ||
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001053 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001054 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001055 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001056 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001057
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001058 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
1059 && test_bit(CONF_STATE2_DEVICE,
1060 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001061 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001062 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001063 continue;
1064 }
1065
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001066 l2cap_send_conn_req(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001067
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001068 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001069 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001070 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001071 rsp.scid = cpu_to_le16(chan->dcid);
1072 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001073
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001074 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001075 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001076 if (test_bit(BT_SK_DEFER_SETUP,
1077 &bt_sk(sk)->flags)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001078 struct sock *parent = bt_sk(sk)->parent;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001079 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1080 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Ilia Kolomisnky05e9a2f2011-07-15 18:30:21 +00001081 if (parent)
1082 parent->sk_data_ready(parent, 0);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001083
1084 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001085 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001086 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1087 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001088 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001089 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001090 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001091 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1092 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001093 }
1094
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001095 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
1096 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001097
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001098 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001099 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001100 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001101 continue;
1102 }
1103
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001104 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001105 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001106 l2cap_build_conf_req(chan, buf), buf);
1107 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001108 }
1109
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001110 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001111 }
1112
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001113 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001114}
1115
Ido Yarivc2287682012-04-20 15:46:07 -03001116/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001117 * Returns closest match, locked.
1118 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001119static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001120 bdaddr_t *src,
1121 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001122{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001123 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001124
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001125 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001126
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001127 list_for_each_entry(c, &chan_list, global_l) {
1128 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001129
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001130 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001131 continue;
1132
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001133 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001134 int src_match, dst_match;
1135 int src_any, dst_any;
1136
Ville Tervob62f3282011-02-10 22:38:50 -03001137 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001138 src_match = !bacmp(&bt_sk(sk)->src, src);
1139 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1140 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001141 read_unlock(&chan_list_lock);
1142 return c;
1143 }
Ville Tervob62f3282011-02-10 22:38:50 -03001144
1145 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001146 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1147 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1148 if ((src_match && dst_any) || (src_any && dst_match) ||
1149 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001150 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001151 }
1152 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001153
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001154 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001155
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001156 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001157}
1158
1159static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1160{
Gustavo F. Padovanc916fbe2011-04-04 16:00:55 -03001161 struct sock *parent, *sk;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001162 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001163
1164 BT_DBG("");
1165
1166 /* Check if we have socket listening on cid */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001167 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
Ido Yarivc2287682012-04-20 15:46:07 -03001168 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001169 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001170 return;
1171
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001172 parent = pchan->sk;
1173
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001174 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001175
Gustavo Padovan80b98022012-05-27 22:27:51 -03001176 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001177 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001178 goto clean;
1179
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001180 sk = chan->sk;
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001181
Ville Tervob62f3282011-02-10 22:38:50 -03001182 hci_conn_hold(conn->hcon);
1183
Ville Tervob62f3282011-02-10 22:38:50 -03001184 bacpy(&bt_sk(sk)->src, conn->src);
1185 bacpy(&bt_sk(sk)->dst, conn->dst);
1186
Gustavo F. Padovand1010242011-03-25 00:39:48 -03001187 bt_accept_enqueue(parent, sk);
1188
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001189 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001190
Gustavo Padovan6754e0d2012-05-25 09:30:56 -03001191 l2cap_chan_ready(chan);
Ville Tervob62f3282011-02-10 22:38:50 -03001192
Ville Tervob62f3282011-02-10 22:38:50 -03001193clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001194 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001195}
1196
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001197static void l2cap_conn_ready(struct l2cap_conn *conn)
1198{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001199 struct l2cap_chan *chan;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001200
1201 BT_DBG("conn %p", conn);
1202
Ville Tervob62f3282011-02-10 22:38:50 -03001203 if (!conn->hcon->out && conn->hcon->type == LE_LINK)
1204 l2cap_le_conn_ready(conn);
1205
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001206 if (conn->hcon->out && conn->hcon->type == LE_LINK)
1207 smp_conn_security(conn, conn->hcon->pending_sec_level);
1208
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001209 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001210
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001211 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001212
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001213 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001214
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001215 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1216 l2cap_chan_unlock(chan);
1217 continue;
1218 }
1219
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001220 if (conn->hcon->type == LE_LINK) {
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001221 if (smp_conn_security(conn, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001222 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001223
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001224 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001225 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001226 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001227 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001228 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001229 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001230 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001231
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001232 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001233 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001234
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001235 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001236 }
1237
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001238 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001239}
1240
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001241/* Notify sockets that we cannot guaranty reliability anymore */
1242static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1243{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001244 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001245
1246 BT_DBG("conn %p", conn);
1247
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001248 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001249
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001250 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001251 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001252 __l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001253 }
1254
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001255 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001256}
1257
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001258static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001259{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001260 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001261 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001262
Marcel Holtmann984947d2009-02-06 23:35:19 +01001263 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001264 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001265
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001266 l2cap_conn_start(conn);
1267}
1268
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001269static void l2cap_conn_del(struct hci_conn *hcon, int err)
1270{
1271 struct l2cap_conn *conn = hcon->l2cap_data;
1272 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001273
1274 if (!conn)
1275 return;
1276
1277 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1278
1279 kfree_skb(conn->rx_skb);
1280
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001281 mutex_lock(&conn->chan_lock);
1282
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001283 /* Kill channels */
1284 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001285 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001286 l2cap_chan_lock(chan);
1287
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001288 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001289
1290 l2cap_chan_unlock(chan);
1291
Gustavo Padovan80b98022012-05-27 22:27:51 -03001292 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001293 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001294 }
1295
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001296 mutex_unlock(&conn->chan_lock);
1297
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001298 hci_chan_del(conn->hchan);
1299
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001300 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001301 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001302
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001303 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001304 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001305 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001306 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001307
1308 hcon->l2cap_data = NULL;
1309 kfree(conn);
1310}
1311
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001312static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001313{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001314 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
1315 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001316
Johan Hedbergd06cc412012-06-06 18:44:11 +08001317 BT_DBG("conn %p", conn);
1318
1319 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1320 smp_chan_destroy(conn);
1321 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1322 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001323}
1324
Linus Torvalds1da177e2005-04-16 15:20:36 -07001325static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
1326{
Marcel Holtmann01394182006-07-03 10:02:46 +02001327 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001328 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329
Marcel Holtmann01394182006-07-03 10:02:46 +02001330 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331 return conn;
1332
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001333 hchan = hci_chan_create(hcon);
1334 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001337 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
1338 if (!conn) {
1339 hci_chan_del(hchan);
1340 return NULL;
1341 }
1342
Linus Torvalds1da177e2005-04-16 15:20:36 -07001343 hcon->l2cap_data = conn;
1344 conn->hcon = hcon;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001345 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001347 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001348
Ville Tervoacd7d372011-02-10 22:38:49 -03001349 if (hcon->hdev->le_mtu && hcon->type == LE_LINK)
1350 conn->mtu = hcon->hdev->le_mtu;
1351 else
1352 conn->mtu = hcon->hdev->acl_mtu;
1353
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354 conn->src = &hcon->hdev->bdaddr;
1355 conn->dst = &hcon->dst;
1356
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001357 conn->feat_mask = 0;
1358
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001360 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001361
1362 INIT_LIST_HEAD(&conn->chan_l);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001364 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001365 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001366 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001367 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001368
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001369 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001370
Linus Torvalds1da177e2005-04-16 15:20:36 -07001371 return conn;
1372}
1373
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375
Ido Yarivc2287682012-04-20 15:46:07 -03001376/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377 * Returns closest match.
1378 */
Ido Yarivc2287682012-04-20 15:46:07 -03001379static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1380 bdaddr_t *src,
1381 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001383 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001385 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001386
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001387 list_for_each_entry(c, &chan_list, global_l) {
1388 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001389
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001390 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001391 continue;
1392
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001393 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001394 int src_match, dst_match;
1395 int src_any, dst_any;
1396
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001398 src_match = !bacmp(&bt_sk(sk)->src, src);
1399 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1400 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001401 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001402 return c;
1403 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404
1405 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001406 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1407 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1408 if ((src_match && dst_any) || (src_any && dst_match) ||
1409 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001410 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411 }
1412 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001414 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001415
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001416 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001417}
1418
Andre Guedes8e9f9892012-04-24 21:02:55 -03001419int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1420 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001422 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424 struct l2cap_conn *conn;
1425 struct hci_conn *hcon;
1426 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001427 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001428 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429
Andre Guedes8e9f9892012-04-24 21:02:55 -03001430 BT_DBG("%s -> %s (type %u) psm 0x%2.2x", batostr(src), batostr(dst),
1431 dst_type, __le16_to_cpu(chan->psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001433 hdev = hci_get_route(dst, src);
1434 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435 return -EHOSTUNREACH;
1436
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001437 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001438
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001439 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001440
1441 /* PSM must be odd and lsb of upper byte must be 0 */
1442 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
1443 chan->chan_type != L2CAP_CHAN_RAW) {
1444 err = -EINVAL;
1445 goto done;
1446 }
1447
1448 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1449 err = -EINVAL;
1450 goto done;
1451 }
1452
1453 switch (chan->mode) {
1454 case L2CAP_MODE_BASIC:
1455 break;
1456 case L2CAP_MODE_ERTM:
1457 case L2CAP_MODE_STREAMING:
1458 if (!disable_ertm)
1459 break;
1460 /* fall through */
1461 default:
1462 err = -ENOTSUPP;
1463 goto done;
1464 }
1465
Gustavo Padovan0797e012012-05-27 22:27:54 -03001466 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001467 case BT_CONNECT:
1468 case BT_CONNECT2:
1469 case BT_CONFIG:
1470 /* Already connecting */
1471 err = 0;
1472 goto done;
1473
1474 case BT_CONNECTED:
1475 /* Already connected */
1476 err = -EISCONN;
1477 goto done;
1478
1479 case BT_OPEN:
1480 case BT_BOUND:
1481 /* Can connect */
1482 break;
1483
1484 default:
1485 err = -EBADFD;
1486 goto done;
1487 }
1488
1489 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001490 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001491 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001492 release_sock(sk);
1493
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001494 chan->psm = psm;
1495 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001497 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001498
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001499 if (chan->dcid == L2CAP_CID_LE_DATA)
Andre Guedes8e9f9892012-04-24 21:02:55 -03001500 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001501 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001502 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001503 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001504 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001505
Ville Tervo30e76272011-02-22 16:10:53 -03001506 if (IS_ERR(hcon)) {
1507 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001508 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001509 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510
1511 conn = l2cap_conn_add(hcon, 0);
1512 if (!conn) {
1513 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001514 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515 goto done;
1516 }
1517
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001518 if (hcon->type == LE_LINK) {
1519 err = 0;
1520
1521 if (!list_empty(&conn->chan_l)) {
1522 err = -EBUSY;
1523 hci_conn_put(hcon);
1524 }
1525
1526 if (err)
1527 goto done;
1528 }
1529
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530 /* Update source addr of the socket */
1531 bacpy(src, conn->src);
1532
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001533 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001534 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001535 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001536
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001537 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001538 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539
1540 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001541 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001542 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001543 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001544 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001545 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001546 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001547 }
1548
Ville Tervo30e76272011-02-22 16:10:53 -03001549 err = 0;
1550
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001552 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001553 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554 hci_dev_put(hdev);
1555 return err;
1556}
1557
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001558int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001559{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001560 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001561 DECLARE_WAITQUEUE(wait, current);
1562 int err = 0;
1563 int timeo = HZ/5;
1564
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001565 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001566 set_current_state(TASK_INTERRUPTIBLE);
1567 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001568 if (!timeo)
1569 timeo = HZ/5;
1570
1571 if (signal_pending(current)) {
1572 err = sock_intr_errno(timeo);
1573 break;
1574 }
1575
1576 release_sock(sk);
1577 timeo = schedule_timeout(timeo);
1578 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001579 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001580
1581 err = sock_error(sk);
1582 if (err)
1583 break;
1584 }
1585 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001586 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001587 return err;
1588}
1589
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001590static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001591{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001592 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001593 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001594
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001595 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001596
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001597 l2cap_chan_lock(chan);
1598
Mat Martineau80909e02012-05-17 20:53:50 -07001599 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001600 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001601 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001602 return;
1603 }
1604
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001605 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001606
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001607 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001608 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001609}
1610
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001611static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001612{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001613 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001614 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001615
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001616 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001617
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001618 l2cap_chan_lock(chan);
1619
Mat Martineau80909e02012-05-17 20:53:50 -07001620 if (!chan->conn) {
1621 l2cap_chan_unlock(chan);
1622 l2cap_chan_put(chan);
1623 return;
1624 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001625
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001626 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001627 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001628 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001629}
1630
Gustavo Padovand6603662012-05-21 13:58:22 -03001631static void l2cap_streaming_send(struct l2cap_chan *chan,
1632 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001633{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001634 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001635 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001636
Mat Martineau37339372012-05-17 20:53:33 -07001637 BT_DBG("chan %p, skbs %p", chan, skbs);
1638
Mat Martineau37339372012-05-17 20:53:33 -07001639 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1640
1641 while (!skb_queue_empty(&chan->tx_q)) {
1642
1643 skb = skb_dequeue(&chan->tx_q);
1644
1645 bt_cb(skb)->control.retries = 1;
1646 control = &bt_cb(skb)->control;
1647
1648 control->reqseq = 0;
1649 control->txseq = chan->next_tx_seq;
1650
1651 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001652
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001653 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001654 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1655 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001656 }
1657
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001658 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001659
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001660 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001661
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001662 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001663 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001664 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001665}
1666
Szymon Janc67c9e842011-07-28 16:24:33 +02001667static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001668{
1669 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001670 struct l2cap_ctrl *control;
1671 int sent = 0;
1672
1673 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001674
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001675 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001676 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001677
Mat Martineau94122bb2012-05-02 09:42:02 -07001678 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1679 return 0;
1680
Mat Martineau18a48e72012-05-17 20:53:34 -07001681 while (chan->tx_send_head &&
1682 chan->unacked_frames < chan->remote_tx_win &&
1683 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001684
Mat Martineau18a48e72012-05-17 20:53:34 -07001685 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001686
Mat Martineau18a48e72012-05-17 20:53:34 -07001687 bt_cb(skb)->control.retries = 1;
1688 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001689
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001690 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001691 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001692
Mat Martineau18a48e72012-05-17 20:53:34 -07001693 control->reqseq = chan->buffer_seq;
1694 chan->last_acked_seq = chan->buffer_seq;
1695 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001696
Mat Martineau18a48e72012-05-17 20:53:34 -07001697 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001698
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001699 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001700 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1701 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001702 }
1703
Mat Martineau18a48e72012-05-17 20:53:34 -07001704 /* Clone after data has been modified. Data is assumed to be
1705 read-only (for locking purposes) on cloned sk_buffs.
1706 */
1707 tx_skb = skb_clone(skb, GFP_KERNEL);
1708
1709 if (!tx_skb)
1710 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001711
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001712 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001713
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001714 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07001715 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03001716 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07001717 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001718
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001719 if (skb_queue_is_last(&chan->tx_q, skb))
1720 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001721 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001722 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07001723
1724 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001725 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001726 }
1727
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001728 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
1729 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07001730
1731 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001732}
1733
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001734static void l2cap_ertm_resend(struct l2cap_chan *chan)
1735{
1736 struct l2cap_ctrl control;
1737 struct sk_buff *skb;
1738 struct sk_buff *tx_skb;
1739 u16 seq;
1740
1741 BT_DBG("chan %p", chan);
1742
1743 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1744 return;
1745
1746 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
1747 seq = l2cap_seq_list_pop(&chan->retrans_list);
1748
1749 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
1750 if (!skb) {
1751 BT_DBG("Error: Can't retransmit seq %d, frame missing",
1752 seq);
1753 continue;
1754 }
1755
1756 bt_cb(skb)->control.retries++;
1757 control = bt_cb(skb)->control;
1758
1759 if (chan->max_tx != 0 &&
1760 bt_cb(skb)->control.retries > chan->max_tx) {
1761 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
1762 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
1763 l2cap_seq_list_clear(&chan->retrans_list);
1764 break;
1765 }
1766
1767 control.reqseq = chan->buffer_seq;
1768 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
1769 control.final = 1;
1770 else
1771 control.final = 0;
1772
1773 if (skb_cloned(skb)) {
1774 /* Cloned sk_buffs are read-only, so we need a
1775 * writeable copy
1776 */
1777 tx_skb = skb_copy(skb, GFP_ATOMIC);
1778 } else {
1779 tx_skb = skb_clone(skb, GFP_ATOMIC);
1780 }
1781
1782 if (!tx_skb) {
1783 l2cap_seq_list_clear(&chan->retrans_list);
1784 break;
1785 }
1786
1787 /* Update skb contents */
1788 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
1789 put_unaligned_le32(__pack_extended_control(&control),
1790 tx_skb->data + L2CAP_HDR_SIZE);
1791 } else {
1792 put_unaligned_le16(__pack_enhanced_control(&control),
1793 tx_skb->data + L2CAP_HDR_SIZE);
1794 }
1795
1796 if (chan->fcs == L2CAP_FCS_CRC16) {
1797 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
1798 put_unaligned_le16(fcs, skb_put(tx_skb,
1799 L2CAP_FCS_SIZE));
1800 }
1801
1802 l2cap_do_send(chan, tx_skb);
1803
1804 BT_DBG("Resent txseq %d", control.txseq);
1805
1806 chan->last_acked_seq = chan->buffer_seq;
1807 }
1808}
1809
Mat Martineauf80842a2012-05-17 20:53:46 -07001810static void l2cap_retransmit(struct l2cap_chan *chan,
1811 struct l2cap_ctrl *control)
1812{
1813 BT_DBG("chan %p, control %p", chan, control);
1814
1815 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
1816 l2cap_ertm_resend(chan);
1817}
1818
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001819static void l2cap_retransmit_all(struct l2cap_chan *chan,
1820 struct l2cap_ctrl *control)
1821{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001822 struct sk_buff *skb;
1823
1824 BT_DBG("chan %p, control %p", chan, control);
1825
1826 if (control->poll)
1827 set_bit(CONN_SEND_FBIT, &chan->conn_state);
1828
1829 l2cap_seq_list_clear(&chan->retrans_list);
1830
1831 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1832 return;
1833
1834 if (chan->unacked_frames) {
1835 skb_queue_walk(&chan->tx_q, skb) {
1836 if (bt_cb(skb)->control.txseq == control->reqseq ||
1837 skb == chan->tx_send_head)
1838 break;
1839 }
1840
1841 skb_queue_walk_from(&chan->tx_q, skb) {
1842 if (skb == chan->tx_send_head)
1843 break;
1844
1845 l2cap_seq_list_append(&chan->retrans_list,
1846 bt_cb(skb)->control.txseq);
1847 }
1848
1849 l2cap_ertm_resend(chan);
1850 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001851}
1852
Szymon Jancb17e73b2012-01-11 10:59:47 +01001853static void l2cap_send_ack(struct l2cap_chan *chan)
1854{
Mat Martineau0a0aba42012-05-17 20:53:39 -07001855 struct l2cap_ctrl control;
1856 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
1857 chan->last_acked_seq);
1858 int threshold;
1859
1860 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
1861 chan, chan->last_acked_seq, chan->buffer_seq);
1862
1863 memset(&control, 0, sizeof(control));
1864 control.sframe = 1;
1865
1866 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
1867 chan->rx_state == L2CAP_RX_STATE_RECV) {
1868 __clear_ack_timer(chan);
1869 control.super = L2CAP_SUPER_RNR;
1870 control.reqseq = chan->buffer_seq;
1871 l2cap_send_sframe(chan, &control);
1872 } else {
1873 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
1874 l2cap_ertm_send(chan);
1875 /* If any i-frames were sent, they included an ack */
1876 if (chan->buffer_seq == chan->last_acked_seq)
1877 frames_to_ack = 0;
1878 }
1879
1880 /* Ack now if the tx window is 3/4ths full.
1881 * Calculate without mul or div
1882 */
1883 threshold = chan->tx_win;
1884 threshold += threshold << 1;
1885 threshold >>= 2;
1886
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001887 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07001888 threshold);
1889
1890 if (frames_to_ack >= threshold) {
1891 __clear_ack_timer(chan);
1892 control.super = L2CAP_SUPER_RR;
1893 control.reqseq = chan->buffer_seq;
1894 l2cap_send_sframe(chan, &control);
1895 frames_to_ack = 0;
1896 }
1897
1898 if (frames_to_ack)
1899 __set_ack_timer(chan);
1900 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01001901}
1902
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001903static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
1904 struct msghdr *msg, int len,
1905 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001906{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02001907 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001908 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03001909 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001911 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001912 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913
1914 sent += count;
1915 len -= count;
1916
1917 /* Continuation fragments (no L2CAP header) */
1918 frag = &skb_shinfo(skb)->frag_list;
1919 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001920 struct sk_buff *tmp;
1921
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922 count = min_t(unsigned int, conn->mtu, len);
1923
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001924 tmp = chan->ops->alloc_skb(chan, count,
1925 msg->msg_flags & MSG_DONTWAIT);
1926 if (IS_ERR(tmp))
1927 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001928
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001929 *frag = tmp;
1930
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001931 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1932 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001934 (*frag)->priority = skb->priority;
1935
Linus Torvalds1da177e2005-04-16 15:20:36 -07001936 sent += count;
1937 len -= count;
1938
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03001939 skb->len += (*frag)->len;
1940 skb->data_len += (*frag)->len;
1941
Linus Torvalds1da177e2005-04-16 15:20:36 -07001942 frag = &(*frag)->next;
1943 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944
1945 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001946}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001947
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001948static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001949 struct msghdr *msg, size_t len,
1950 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001951{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001952 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001953 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03001954 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001955 struct l2cap_hdr *lh;
1956
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001957 BT_DBG("chan %p len %zu priority %u", chan, len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001958
1959 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001960
1961 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03001962 msg->msg_flags & MSG_DONTWAIT);
1963 if (IS_ERR(skb))
1964 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001965
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001966 skb->priority = priority;
1967
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001968 /* Create L2CAP header */
1969 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001970 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03001971 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
1972 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001973
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02001974 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001975 if (unlikely(err < 0)) {
1976 kfree_skb(skb);
1977 return ERR_PTR(err);
1978 }
1979 return skb;
1980}
1981
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001982static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001983 struct msghdr *msg, size_t len,
1984 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001985{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001986 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001987 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03001988 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001989 struct l2cap_hdr *lh;
1990
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001991 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001992
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03001993 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001994
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03001995 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03001996 msg->msg_flags & MSG_DONTWAIT);
1997 if (IS_ERR(skb))
1998 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001999
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002000 skb->priority = priority;
2001
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002002 /* Create L2CAP header */
2003 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002004 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002005 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002006
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002007 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002008 if (unlikely(err < 0)) {
2009 kfree_skb(skb);
2010 return ERR_PTR(err);
2011 }
2012 return skb;
2013}
2014
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002015static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002016 struct msghdr *msg, size_t len,
2017 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002018{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002019 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002020 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002021 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002022 struct l2cap_hdr *lh;
2023
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002024 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002025
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002026 if (!conn)
2027 return ERR_PTR(-ENOTCONN);
2028
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002029 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002030
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002031 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002032 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002033
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002034 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002035 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002036
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002037 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002038
2039 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002040 msg->msg_flags & MSG_DONTWAIT);
2041 if (IS_ERR(skb))
2042 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002043
2044 /* Create L2CAP header */
2045 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002046 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002047 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002048
Mat Martineau18a48e72012-05-17 20:53:34 -07002049 /* Control header is populated later */
2050 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2051 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2052 else
2053 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002054
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002055 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002056 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002057
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002058 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002059 if (unlikely(err < 0)) {
2060 kfree_skb(skb);
2061 return ERR_PTR(err);
2062 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002063
Mat Martineau18a48e72012-05-17 20:53:34 -07002064 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002065 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002066 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002067}
2068
Mat Martineau94122bb2012-05-02 09:42:02 -07002069static int l2cap_segment_sdu(struct l2cap_chan *chan,
2070 struct sk_buff_head *seg_queue,
2071 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002072{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002073 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002074 u16 sdu_len;
2075 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002076 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002077
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002078 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002079
Mat Martineau94122bb2012-05-02 09:42:02 -07002080 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2081 * so fragmented skbs are not used. The HCI layer's handling
2082 * of fragmented skbs is not compatible with ERTM's queueing.
2083 */
2084
2085 /* PDU size is derived from the HCI MTU */
2086 pdu_len = chan->conn->mtu;
2087
2088 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
2089
2090 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002091 if (chan->fcs)
2092 pdu_len -= L2CAP_FCS_SIZE;
2093
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002094 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002095
2096 /* Remote device may have requested smaller PDUs */
2097 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2098
2099 if (len <= pdu_len) {
2100 sar = L2CAP_SAR_UNSEGMENTED;
2101 sdu_len = 0;
2102 pdu_len = len;
2103 } else {
2104 sar = L2CAP_SAR_START;
2105 sdu_len = len;
2106 pdu_len -= L2CAP_SDULEN_SIZE;
2107 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002108
2109 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002110 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002111
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002112 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002113 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002114 return PTR_ERR(skb);
2115 }
2116
Mat Martineau94122bb2012-05-02 09:42:02 -07002117 bt_cb(skb)->control.sar = sar;
2118 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002119
Mat Martineau94122bb2012-05-02 09:42:02 -07002120 len -= pdu_len;
2121 if (sdu_len) {
2122 sdu_len = 0;
2123 pdu_len += L2CAP_SDULEN_SIZE;
2124 }
2125
2126 if (len <= pdu_len) {
2127 sar = L2CAP_SAR_END;
2128 pdu_len = len;
2129 } else {
2130 sar = L2CAP_SAR_CONTINUE;
2131 }
2132 }
2133
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002134 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002135}
2136
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002137int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
2138 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002139{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002140 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002141 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002142 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002143
2144 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002145 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002146 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002147 if (IS_ERR(skb))
2148 return PTR_ERR(skb);
2149
2150 l2cap_do_send(chan, skb);
2151 return len;
2152 }
2153
2154 switch (chan->mode) {
2155 case L2CAP_MODE_BASIC:
2156 /* Check outgoing MTU */
2157 if (len > chan->omtu)
2158 return -EMSGSIZE;
2159
2160 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002161 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002162 if (IS_ERR(skb))
2163 return PTR_ERR(skb);
2164
2165 l2cap_do_send(chan, skb);
2166 err = len;
2167 break;
2168
2169 case L2CAP_MODE_ERTM:
2170 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002171 /* Check outgoing MTU */
2172 if (len > chan->omtu) {
2173 err = -EMSGSIZE;
2174 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002175 }
2176
Mat Martineau94122bb2012-05-02 09:42:02 -07002177 __skb_queue_head_init(&seg_queue);
2178
2179 /* Do segmentation before calling in to the state machine,
2180 * since it's possible to block while waiting for memory
2181 * allocation.
2182 */
2183 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2184
2185 /* The channel could have been closed while segmenting,
2186 * check that it is still connected.
2187 */
2188 if (chan->state != BT_CONNECTED) {
2189 __skb_queue_purge(&seg_queue);
2190 err = -ENOTCONN;
2191 }
2192
2193 if (err)
2194 break;
2195
Mat Martineau37339372012-05-17 20:53:33 -07002196 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002197 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002198 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002199 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002200
Gustavo Padovand6603662012-05-21 13:58:22 -03002201 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002202
Mat Martineau94122bb2012-05-02 09:42:02 -07002203 /* If the skbs were not queued for sending, they'll still be in
2204 * seg_queue and need to be purged.
2205 */
2206 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002207 break;
2208
2209 default:
2210 BT_DBG("bad state %1.1x", chan->mode);
2211 err = -EBADFD;
2212 }
2213
2214 return err;
2215}
2216
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002217static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2218{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002219 struct l2cap_ctrl control;
2220 u16 seq;
2221
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002222 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002223
2224 memset(&control, 0, sizeof(control));
2225 control.sframe = 1;
2226 control.super = L2CAP_SUPER_SREJ;
2227
2228 for (seq = chan->expected_tx_seq; seq != txseq;
2229 seq = __next_seq(chan, seq)) {
2230 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2231 control.reqseq = seq;
2232 l2cap_send_sframe(chan, &control);
2233 l2cap_seq_list_append(&chan->srej_list, seq);
2234 }
2235 }
2236
2237 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002238}
2239
2240static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2241{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002242 struct l2cap_ctrl control;
2243
2244 BT_DBG("chan %p", chan);
2245
2246 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2247 return;
2248
2249 memset(&control, 0, sizeof(control));
2250 control.sframe = 1;
2251 control.super = L2CAP_SUPER_SREJ;
2252 control.reqseq = chan->srej_list.tail;
2253 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002254}
2255
2256static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2257{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002258 struct l2cap_ctrl control;
2259 u16 initial_head;
2260 u16 seq;
2261
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002262 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002263
2264 memset(&control, 0, sizeof(control));
2265 control.sframe = 1;
2266 control.super = L2CAP_SUPER_SREJ;
2267
2268 /* Capture initial list head to allow only one pass through the list. */
2269 initial_head = chan->srej_list.head;
2270
2271 do {
2272 seq = l2cap_seq_list_pop(&chan->srej_list);
2273 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2274 break;
2275
2276 control.reqseq = seq;
2277 l2cap_send_sframe(chan, &control);
2278 l2cap_seq_list_append(&chan->srej_list, seq);
2279 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002280}
2281
Mat Martineau608bcc62012-05-17 20:53:32 -07002282static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2283{
2284 struct sk_buff *acked_skb;
2285 u16 ackseq;
2286
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002287 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002288
2289 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2290 return;
2291
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002292 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002293 chan->expected_ack_seq, chan->unacked_frames);
2294
2295 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2296 ackseq = __next_seq(chan, ackseq)) {
2297
2298 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2299 if (acked_skb) {
2300 skb_unlink(acked_skb, &chan->tx_q);
2301 kfree_skb(acked_skb);
2302 chan->unacked_frames--;
2303 }
2304 }
2305
2306 chan->expected_ack_seq = reqseq;
2307
2308 if (chan->unacked_frames == 0)
2309 __clear_retrans_timer(chan);
2310
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002311 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002312}
2313
2314static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2315{
2316 BT_DBG("chan %p", chan);
2317
2318 chan->expected_tx_seq = chan->buffer_seq;
2319 l2cap_seq_list_clear(&chan->srej_list);
2320 skb_queue_purge(&chan->srej_q);
2321 chan->rx_state = L2CAP_RX_STATE_RECV;
2322}
2323
Gustavo Padovand6603662012-05-21 13:58:22 -03002324static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2325 struct l2cap_ctrl *control,
2326 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002327{
Mat Martineau608bcc62012-05-17 20:53:32 -07002328 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2329 event);
2330
2331 switch (event) {
2332 case L2CAP_EV_DATA_REQUEST:
2333 if (chan->tx_send_head == NULL)
2334 chan->tx_send_head = skb_peek(skbs);
2335
2336 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2337 l2cap_ertm_send(chan);
2338 break;
2339 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2340 BT_DBG("Enter LOCAL_BUSY");
2341 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2342
2343 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2344 /* The SREJ_SENT state must be aborted if we are to
2345 * enter the LOCAL_BUSY state.
2346 */
2347 l2cap_abort_rx_srej_sent(chan);
2348 }
2349
2350 l2cap_send_ack(chan);
2351
2352 break;
2353 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2354 BT_DBG("Exit LOCAL_BUSY");
2355 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2356
2357 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2358 struct l2cap_ctrl local_control;
2359
2360 memset(&local_control, 0, sizeof(local_control));
2361 local_control.sframe = 1;
2362 local_control.super = L2CAP_SUPER_RR;
2363 local_control.poll = 1;
2364 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002365 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002366
2367 chan->retry_count = 1;
2368 __set_monitor_timer(chan);
2369 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2370 }
2371 break;
2372 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2373 l2cap_process_reqseq(chan, control->reqseq);
2374 break;
2375 case L2CAP_EV_EXPLICIT_POLL:
2376 l2cap_send_rr_or_rnr(chan, 1);
2377 chan->retry_count = 1;
2378 __set_monitor_timer(chan);
2379 __clear_ack_timer(chan);
2380 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2381 break;
2382 case L2CAP_EV_RETRANS_TO:
2383 l2cap_send_rr_or_rnr(chan, 1);
2384 chan->retry_count = 1;
2385 __set_monitor_timer(chan);
2386 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2387 break;
2388 case L2CAP_EV_RECV_FBIT:
2389 /* Nothing to process */
2390 break;
2391 default:
2392 break;
2393 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002394}
2395
Gustavo Padovand6603662012-05-21 13:58:22 -03002396static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2397 struct l2cap_ctrl *control,
2398 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002399{
Mat Martineau608bcc62012-05-17 20:53:32 -07002400 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2401 event);
2402
2403 switch (event) {
2404 case L2CAP_EV_DATA_REQUEST:
2405 if (chan->tx_send_head == NULL)
2406 chan->tx_send_head = skb_peek(skbs);
2407 /* Queue data, but don't send. */
2408 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2409 break;
2410 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2411 BT_DBG("Enter LOCAL_BUSY");
2412 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2413
2414 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2415 /* The SREJ_SENT state must be aborted if we are to
2416 * enter the LOCAL_BUSY state.
2417 */
2418 l2cap_abort_rx_srej_sent(chan);
2419 }
2420
2421 l2cap_send_ack(chan);
2422
2423 break;
2424 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2425 BT_DBG("Exit LOCAL_BUSY");
2426 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2427
2428 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2429 struct l2cap_ctrl local_control;
2430 memset(&local_control, 0, sizeof(local_control));
2431 local_control.sframe = 1;
2432 local_control.super = L2CAP_SUPER_RR;
2433 local_control.poll = 1;
2434 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002435 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002436
2437 chan->retry_count = 1;
2438 __set_monitor_timer(chan);
2439 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2440 }
2441 break;
2442 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2443 l2cap_process_reqseq(chan, control->reqseq);
2444
2445 /* Fall through */
2446
2447 case L2CAP_EV_RECV_FBIT:
2448 if (control && control->final) {
2449 __clear_monitor_timer(chan);
2450 if (chan->unacked_frames > 0)
2451 __set_retrans_timer(chan);
2452 chan->retry_count = 0;
2453 chan->tx_state = L2CAP_TX_STATE_XMIT;
2454 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2455 }
2456 break;
2457 case L2CAP_EV_EXPLICIT_POLL:
2458 /* Ignore */
2459 break;
2460 case L2CAP_EV_MONITOR_TO:
2461 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2462 l2cap_send_rr_or_rnr(chan, 1);
2463 __set_monitor_timer(chan);
2464 chan->retry_count++;
2465 } else {
2466 l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
2467 }
2468 break;
2469 default:
2470 break;
2471 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002472}
2473
Gustavo Padovand6603662012-05-21 13:58:22 -03002474static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2475 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002476{
Mat Martineau608bcc62012-05-17 20:53:32 -07002477 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2478 chan, control, skbs, event, chan->tx_state);
2479
2480 switch (chan->tx_state) {
2481 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002482 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002483 break;
2484 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002485 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002486 break;
2487 default:
2488 /* Ignore event */
2489 break;
2490 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002491}
2492
Mat Martineau4b51dae92012-05-17 20:53:37 -07002493static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2494 struct l2cap_ctrl *control)
2495{
2496 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002497 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002498}
2499
Mat Martineauf80842a2012-05-17 20:53:46 -07002500static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2501 struct l2cap_ctrl *control)
2502{
2503 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002504 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002505}
2506
Linus Torvalds1da177e2005-04-16 15:20:36 -07002507/* Copy frame to all raw sockets on that connection */
2508static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2509{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002510 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002511 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002512
2513 BT_DBG("conn %p", conn);
2514
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002515 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002516
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002517 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002518 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002519 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002520 continue;
2521
2522 /* Don't send frame to the socket it came from */
2523 if (skb->sk == sk)
2524 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002525 nskb = skb_clone(skb, GFP_ATOMIC);
2526 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002527 continue;
2528
Gustavo Padovan80b98022012-05-27 22:27:51 -03002529 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002530 kfree_skb(nskb);
2531 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002532
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002533 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002534}
2535
2536/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002537static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2538 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002539{
2540 struct sk_buff *skb, **frag;
2541 struct l2cap_cmd_hdr *cmd;
2542 struct l2cap_hdr *lh;
2543 int len, count;
2544
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002545 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2546 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002547
2548 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2549 count = min_t(unsigned int, conn->mtu, len);
2550
2551 skb = bt_skb_alloc(count, GFP_ATOMIC);
2552 if (!skb)
2553 return NULL;
2554
2555 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002556 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002557
2558 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002559 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002560 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002561 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002562
2563 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2564 cmd->code = code;
2565 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002566 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567
2568 if (dlen) {
2569 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2570 memcpy(skb_put(skb, count), data, count);
2571 data += count;
2572 }
2573
2574 len -= skb->len;
2575
2576 /* Continuation fragments (no L2CAP header) */
2577 frag = &skb_shinfo(skb)->frag_list;
2578 while (len) {
2579 count = min_t(unsigned int, conn->mtu, len);
2580
2581 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2582 if (!*frag)
2583 goto fail;
2584
2585 memcpy(skb_put(*frag, count), data, count);
2586
2587 len -= count;
2588 data += count;
2589
2590 frag = &(*frag)->next;
2591 }
2592
2593 return skb;
2594
2595fail:
2596 kfree_skb(skb);
2597 return NULL;
2598}
2599
2600static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2601{
2602 struct l2cap_conf_opt *opt = *ptr;
2603 int len;
2604
2605 len = L2CAP_CONF_OPT_SIZE + opt->len;
2606 *ptr += len;
2607
2608 *type = opt->type;
2609 *olen = opt->len;
2610
2611 switch (opt->len) {
2612 case 1:
2613 *val = *((u8 *) opt->val);
2614 break;
2615
2616 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002617 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002618 break;
2619
2620 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002621 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002622 break;
2623
2624 default:
2625 *val = (unsigned long) opt->val;
2626 break;
2627 }
2628
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002629 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002630 return len;
2631}
2632
Linus Torvalds1da177e2005-04-16 15:20:36 -07002633static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2634{
2635 struct l2cap_conf_opt *opt = *ptr;
2636
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002637 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002638
2639 opt->type = type;
2640 opt->len = len;
2641
2642 switch (len) {
2643 case 1:
2644 *((u8 *) opt->val) = val;
2645 break;
2646
2647 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002648 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002649 break;
2650
2651 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002652 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002653 break;
2654
2655 default:
2656 memcpy(opt->val, (void *) val, len);
2657 break;
2658 }
2659
2660 *ptr += L2CAP_CONF_OPT_SIZE + len;
2661}
2662
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002663static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2664{
2665 struct l2cap_conf_efs efs;
2666
Szymon Janc1ec918c2011-11-16 09:32:21 +01002667 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002668 case L2CAP_MODE_ERTM:
2669 efs.id = chan->local_id;
2670 efs.stype = chan->local_stype;
2671 efs.msdu = cpu_to_le16(chan->local_msdu);
2672 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002673 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
2674 efs.flush_to = __constant_cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002675 break;
2676
2677 case L2CAP_MODE_STREAMING:
2678 efs.id = 1;
2679 efs.stype = L2CAP_SERV_BESTEFFORT;
2680 efs.msdu = cpu_to_le16(chan->local_msdu);
2681 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2682 efs.acc_lat = 0;
2683 efs.flush_to = 0;
2684 break;
2685
2686 default:
2687 return;
2688 }
2689
2690 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
2691 (unsigned long) &efs);
2692}
2693
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002694static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002695{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002696 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07002697 ack_timer.work);
2698 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002699
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02002700 BT_DBG("chan %p", chan);
2701
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002702 l2cap_chan_lock(chan);
2703
Mat Martineau03625202012-05-17 20:53:51 -07002704 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2705 chan->last_acked_seq);
2706
2707 if (frames_to_ack)
2708 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002709
2710 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01002711 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002712}
2713
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03002714int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002715{
Mat Martineau3c588192012-04-11 10:48:42 -07002716 int err;
2717
Mat Martineau105bdf92012-04-27 16:50:48 -07002718 chan->next_tx_seq = 0;
2719 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002720 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002721 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002722 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002723 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07002724 chan->last_acked_seq = 0;
2725 chan->sdu = NULL;
2726 chan->sdu_last_frag = NULL;
2727 chan->sdu_len = 0;
2728
Mat Martineaud34c34f2012-05-14 14:49:27 -07002729 skb_queue_head_init(&chan->tx_q);
2730
Mat Martineau105bdf92012-04-27 16:50:48 -07002731 if (chan->mode != L2CAP_MODE_ERTM)
2732 return 0;
2733
2734 chan->rx_state = L2CAP_RX_STATE_RECV;
2735 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002736
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002737 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
2738 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
2739 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002740
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03002741 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002742
Mat Martineau3c588192012-04-11 10:48:42 -07002743 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
2744 if (err < 0)
2745 return err;
2746
Mat Martineau9dc9aff2012-05-17 16:20:14 -07002747 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
2748 if (err < 0)
2749 l2cap_seq_list_free(&chan->srej_list);
2750
2751 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002752}
2753
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002754static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2755{
2756 switch (mode) {
2757 case L2CAP_MODE_STREAMING:
2758 case L2CAP_MODE_ERTM:
2759 if (l2cap_mode_supported(mode, remote_feat_mask))
2760 return mode;
2761 /* fall through */
2762 default:
2763 return L2CAP_MODE_BASIC;
2764 }
2765}
2766
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002767static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
2768{
2769 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
2770}
2771
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002772static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
2773{
2774 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
2775}
2776
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002777static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
2778{
2779 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002780 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002781 /* use extended control field */
2782 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002783 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
2784 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002785 chan->tx_win = min_t(u16, chan->tx_win,
2786 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002787 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
2788 }
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002789}
2790
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03002791static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002792{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002793 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002794 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002795 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002796 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002797
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03002798 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002799
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002800 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002801 goto done;
2802
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002803 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002804 case L2CAP_MODE_STREAMING:
2805 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002806 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002807 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002808
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002809 if (__l2cap_efs_supported(chan))
2810 set_bit(FLAG_EFS_ENABLE, &chan->flags);
2811
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002812 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002813 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002814 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002815 break;
2816 }
2817
2818done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002819 if (chan->imtu != L2CAP_DEFAULT_MTU)
2820 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02002821
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002822 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002823 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002824 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
2825 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002826 break;
2827
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002828 rfc.mode = L2CAP_MODE_BASIC;
2829 rfc.txwin_size = 0;
2830 rfc.max_transmit = 0;
2831 rfc.retrans_timeout = 0;
2832 rfc.monitor_timeout = 0;
2833 rfc.max_pdu_size = 0;
2834
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002835 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2836 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002837 break;
2838
2839 case L2CAP_MODE_ERTM:
2840 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002841 rfc.max_transmit = chan->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002842 rfc.retrans_timeout = 0;
2843 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002844
2845 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
2846 L2CAP_EXT_HDR_SIZE -
2847 L2CAP_SDULEN_SIZE -
2848 L2CAP_FCS_SIZE);
2849 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002850
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002851 l2cap_txwin_setup(chan);
2852
2853 rfc.txwin_size = min_t(u16, chan->tx_win,
2854 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002855
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002856 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2857 (unsigned long) &rfc);
2858
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002859 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2860 l2cap_add_opt_efs(&ptr, chan);
2861
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002862 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002863 break;
2864
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002865 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002866 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002867 chan->fcs = L2CAP_FCS_NONE;
2868 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002869 }
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002870
2871 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2872 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
2873 chan->tx_win);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002874 break;
2875
2876 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07002877 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002878 rfc.mode = L2CAP_MODE_STREAMING;
2879 rfc.txwin_size = 0;
2880 rfc.max_transmit = 0;
2881 rfc.retrans_timeout = 0;
2882 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002883
2884 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
2885 L2CAP_EXT_HDR_SIZE -
2886 L2CAP_SDULEN_SIZE -
2887 L2CAP_FCS_SIZE);
2888 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002889
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002890 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2891 (unsigned long) &rfc);
2892
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002893 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2894 l2cap_add_opt_efs(&ptr, chan);
2895
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002896 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002897 break;
2898
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002899 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002900 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002901 chan->fcs = L2CAP_FCS_NONE;
2902 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002903 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002904 break;
2905 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002906
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002907 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03002908 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002909
2910 return ptr - data;
2911}
2912
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002913static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002914{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002915 struct l2cap_conf_rsp *rsp = data;
2916 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002917 void *req = chan->conf_req;
2918 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002919 int type, hint, olen;
2920 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002921 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002922 struct l2cap_conf_efs efs;
2923 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02002924 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002925 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002926 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002928 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002929
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002930 while (len >= L2CAP_CONF_OPT_SIZE) {
2931 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002932
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002933 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002934 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002935
2936 switch (type) {
2937 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002938 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002939 break;
2940
2941 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002942 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002943 break;
2944
2945 case L2CAP_CONF_QOS:
2946 break;
2947
Marcel Holtmann6464f352007-10-20 13:39:51 +02002948 case L2CAP_CONF_RFC:
2949 if (olen == sizeof(rfc))
2950 memcpy(&rfc, (void *) val, olen);
2951 break;
2952
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002953 case L2CAP_CONF_FCS:
2954 if (val == L2CAP_FCS_NONE)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002955 set_bit(CONF_NO_FCS_RECV, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002956 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002957
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002958 case L2CAP_CONF_EFS:
2959 remote_efs = 1;
2960 if (olen == sizeof(efs))
2961 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002962 break;
2963
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002964 case L2CAP_CONF_EWS:
2965 if (!enable_hs)
2966 return -ECONNREFUSED;
2967
2968 set_bit(FLAG_EXT_CTRL, &chan->flags);
2969 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002970 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002971 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002972 break;
2973
2974 default:
2975 if (hint)
2976 break;
2977
2978 result = L2CAP_CONF_UNKNOWN;
2979 *((u8 *) ptr++) = type;
2980 break;
2981 }
2982 }
2983
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002984 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002985 goto done;
2986
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002987 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002988 case L2CAP_MODE_STREAMING:
2989 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002990 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002991 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002992 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002993 break;
2994 }
2995
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002996 if (remote_efs) {
2997 if (__l2cap_efs_supported(chan))
2998 set_bit(FLAG_EFS_ENABLE, &chan->flags);
2999 else
3000 return -ECONNREFUSED;
3001 }
3002
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003003 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003004 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003005
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003006 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003007 }
3008
3009done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003010 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003011 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003012 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003013
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003014 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003015 return -ECONNREFUSED;
3016
3017 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3018 sizeof(rfc), (unsigned long) &rfc);
3019 }
3020
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003021 if (result == L2CAP_CONF_SUCCESS) {
3022 /* Configure output options and let the other side know
3023 * which ones we don't like. */
3024
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003025 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3026 result = L2CAP_CONF_UNACCEPT;
3027 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003028 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003029 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003030 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003031 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003032
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003033 if (remote_efs) {
3034 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
3035 efs.stype != L2CAP_SERV_NOTRAFIC &&
3036 efs.stype != chan->local_stype) {
3037
3038 result = L2CAP_CONF_UNACCEPT;
3039
3040 if (chan->num_conf_req >= 1)
3041 return -ECONNREFUSED;
3042
3043 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003044 sizeof(efs),
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003045 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003046 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003047 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003048 result = L2CAP_CONF_PENDING;
3049 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003050 }
3051 }
3052
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003053 switch (rfc.mode) {
3054 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003055 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003056 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003057 break;
3058
3059 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003060 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3061 chan->remote_tx_win = rfc.txwin_size;
3062 else
3063 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3064
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003065 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003066
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003067 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
3068 chan->conn->mtu -
3069 L2CAP_EXT_HDR_SIZE -
3070 L2CAP_SDULEN_SIZE -
3071 L2CAP_FCS_SIZE);
3072 rfc.max_pdu_size = cpu_to_le16(size);
3073 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003074
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003075 rfc.retrans_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003076 __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003077 rfc.monitor_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003078 __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003079
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003080 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003081
3082 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3083 sizeof(rfc), (unsigned long) &rfc);
3084
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003085 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3086 chan->remote_id = efs.id;
3087 chan->remote_stype = efs.stype;
3088 chan->remote_msdu = le16_to_cpu(efs.msdu);
3089 chan->remote_flush_to =
3090 le32_to_cpu(efs.flush_to);
3091 chan->remote_acc_lat =
3092 le32_to_cpu(efs.acc_lat);
3093 chan->remote_sdu_itime =
3094 le32_to_cpu(efs.sdu_itime);
3095 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
3096 sizeof(efs), (unsigned long) &efs);
3097 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003098 break;
3099
3100 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003101 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
3102 chan->conn->mtu -
3103 L2CAP_EXT_HDR_SIZE -
3104 L2CAP_SDULEN_SIZE -
3105 L2CAP_FCS_SIZE);
3106 rfc.max_pdu_size = cpu_to_le16(size);
3107 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003108
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003109 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003110
3111 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3112 sizeof(rfc), (unsigned long) &rfc);
3113
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003114 break;
3115
3116 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003117 result = L2CAP_CONF_UNACCEPT;
3118
3119 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003120 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003121 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003122
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003123 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003124 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003125 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003126 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003127 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003128 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003129
3130 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003131}
3132
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003133static 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 -03003134{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003135 struct l2cap_conf_req *req = data;
3136 void *ptr = req->data;
3137 int type, olen;
3138 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003139 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003140 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003141
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003142 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003143
3144 while (len >= L2CAP_CONF_OPT_SIZE) {
3145 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3146
3147 switch (type) {
3148 case L2CAP_CONF_MTU:
3149 if (val < L2CAP_DEFAULT_MIN_MTU) {
3150 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003151 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003152 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003153 chan->imtu = val;
3154 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003155 break;
3156
3157 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003158 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003159 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003160 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003161 break;
3162
3163 case L2CAP_CONF_RFC:
3164 if (olen == sizeof(rfc))
3165 memcpy(&rfc, (void *)val, olen);
3166
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003167 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003168 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003169 return -ECONNREFUSED;
3170
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003171 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003172
3173 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3174 sizeof(rfc), (unsigned long) &rfc);
3175 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003176
3177 case L2CAP_CONF_EWS:
3178 chan->tx_win = min_t(u16, val,
3179 L2CAP_DEFAULT_EXT_WINDOW);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003180 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
3181 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003182 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003183
3184 case L2CAP_CONF_EFS:
3185 if (olen == sizeof(efs))
3186 memcpy(&efs, (void *)val, olen);
3187
3188 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
3189 efs.stype != L2CAP_SERV_NOTRAFIC &&
3190 efs.stype != chan->local_stype)
3191 return -ECONNREFUSED;
3192
3193 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
3194 sizeof(efs), (unsigned long) &efs);
3195 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003196 }
3197 }
3198
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003199 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003200 return -ECONNREFUSED;
3201
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003202 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003203
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003204 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003205 switch (rfc.mode) {
3206 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003207 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3208 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3209 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003210
3211 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3212 chan->local_msdu = le16_to_cpu(efs.msdu);
3213 chan->local_sdu_itime =
3214 le32_to_cpu(efs.sdu_itime);
3215 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3216 chan->local_flush_to =
3217 le32_to_cpu(efs.flush_to);
3218 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003219 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003220
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003221 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003222 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003223 }
3224 }
3225
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003226 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003227 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003228
3229 return ptr - data;
3230}
3231
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003232static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003233{
3234 struct l2cap_conf_rsp *rsp = data;
3235 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003236
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003237 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003238
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003239 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003240 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003241 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003242
3243 return ptr - data;
3244}
3245
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003246void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003247{
3248 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003249 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003250 u8 buf[128];
3251
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003252 rsp.scid = cpu_to_le16(chan->dcid);
3253 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003254 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3255 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003256 l2cap_send_cmd(conn, chan->ident,
3257 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
3258
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003259 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003260 return;
3261
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003262 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3263 l2cap_build_conf_req(chan, buf), buf);
3264 chan->num_conf_req++;
3265}
3266
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003267static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003268{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003269 int type, olen;
3270 unsigned long val;
3271 struct l2cap_conf_rfc rfc;
3272
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003273 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003274
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003275 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003276 return;
3277
3278 while (len >= L2CAP_CONF_OPT_SIZE) {
3279 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3280
Szymon Janc8f321f82012-06-08 11:33:33 +02003281 if (type != L2CAP_CONF_RFC)
3282 continue;
3283
3284 if (olen != sizeof(rfc))
3285 break;
3286
3287 memcpy(&rfc, (void *)val, olen);
3288 goto done;
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003289 }
3290
Mat Martineau36e999a2011-12-08 17:23:21 -08003291 /* Use sane default values in case a misbehaving remote device
3292 * did not send an RFC option.
3293 */
3294 rfc.mode = chan->mode;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003295 rfc.retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3296 rfc.monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
Mat Martineau36e999a2011-12-08 17:23:21 -08003297 rfc.max_pdu_size = cpu_to_le16(chan->imtu);
3298
3299 BT_ERR("Expected RFC option was not found, using defaults");
3300
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003301done:
3302 switch (rfc.mode) {
3303 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003304 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3305 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3306 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003307 break;
3308 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003309 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003310 }
3311}
3312
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003313static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3314{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003315 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003316
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003317 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003318 return 0;
3319
3320 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
3321 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003322 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003323
3324 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003325 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003326
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003327 l2cap_conn_start(conn);
3328 }
3329
3330 return 0;
3331}
3332
Linus Torvalds1da177e2005-04-16 15:20:36 -07003333static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3334{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003335 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3336 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003337 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003338 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003339 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003340
3341 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003342 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003343
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003344 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003345
3346 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003347 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003348 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003349 result = L2CAP_CR_BAD_PSM;
3350 goto sendresp;
3351 }
3352
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003353 parent = pchan->sk;
3354
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003355 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003356 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003357
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003358 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003359 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003360 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003361 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003362 result = L2CAP_CR_SEC_BLOCK;
3363 goto response;
3364 }
3365
Linus Torvalds1da177e2005-04-16 15:20:36 -07003366 result = L2CAP_CR_NO_MEM;
3367
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003368 /* Check if we already have channel with that dcid */
3369 if (__l2cap_get_chan_by_dcid(conn, scid))
3370 goto response;
3371
Gustavo Padovan80b98022012-05-27 22:27:51 -03003372 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003373 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003374 goto response;
3375
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003376 sk = chan->sk;
3377
Linus Torvalds1da177e2005-04-16 15:20:36 -07003378 hci_conn_hold(conn->hcon);
3379
Linus Torvalds1da177e2005-04-16 15:20:36 -07003380 bacpy(&bt_sk(sk)->src, conn->src);
3381 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003382 chan->psm = psm;
3383 chan->dcid = scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003384
Gustavo F. Padovand1010242011-03-25 00:39:48 -03003385 bt_accept_enqueue(parent, sk);
3386
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003387 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003388
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003389 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003390
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003391 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003392
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003393 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003394
Marcel Holtmann984947d2009-02-06 23:35:19 +01003395 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003396 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003397 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003398 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003399 result = L2CAP_CR_PEND;
3400 status = L2CAP_CS_AUTHOR_PEND;
3401 parent->sk_data_ready(parent, 0);
3402 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003403 __l2cap_state_change(chan, BT_CONFIG);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003404 result = L2CAP_CR_SUCCESS;
3405 status = L2CAP_CS_NO_INFO;
3406 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003407 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003408 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003409 result = L2CAP_CR_PEND;
3410 status = L2CAP_CS_AUTHEN_PEND;
3411 }
3412 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003413 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003414 result = L2CAP_CR_PEND;
3415 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003416 }
3417
Linus Torvalds1da177e2005-04-16 15:20:36 -07003418response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003419 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003420 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003421
3422sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003423 rsp.scid = cpu_to_le16(scid);
3424 rsp.dcid = cpu_to_le16(dcid);
3425 rsp.result = cpu_to_le16(result);
3426 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003427 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003428
3429 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3430 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003431 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003432
3433 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3434 conn->info_ident = l2cap_get_ident(conn);
3435
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003436 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003437
3438 l2cap_send_cmd(conn, conn->info_ident,
3439 L2CAP_INFO_REQ, sizeof(info), &info);
3440 }
3441
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003442 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003443 result == L2CAP_CR_SUCCESS) {
3444 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003445 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003446 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003447 l2cap_build_conf_req(chan, buf), buf);
3448 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003449 }
3450
Linus Torvalds1da177e2005-04-16 15:20:36 -07003451 return 0;
3452}
3453
3454static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3455{
3456 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3457 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003458 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003459 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003460 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003461
3462 scid = __le16_to_cpu(rsp->scid);
3463 dcid = __le16_to_cpu(rsp->dcid);
3464 result = __le16_to_cpu(rsp->result);
3465 status = __le16_to_cpu(rsp->status);
3466
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003467 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x",
3468 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003469
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003470 mutex_lock(&conn->chan_lock);
3471
Linus Torvalds1da177e2005-04-16 15:20:36 -07003472 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003473 chan = __l2cap_get_chan_by_scid(conn, scid);
3474 if (!chan) {
3475 err = -EFAULT;
3476 goto unlock;
3477 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003478 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003479 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3480 if (!chan) {
3481 err = -EFAULT;
3482 goto unlock;
3483 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003484 }
3485
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003486 err = 0;
3487
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003488 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003489
Linus Torvalds1da177e2005-04-16 15:20:36 -07003490 switch (result) {
3491 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003492 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003493 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003494 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003495 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003496
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003497 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003498 break;
3499
Linus Torvalds1da177e2005-04-16 15:20:36 -07003500 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003501 l2cap_build_conf_req(chan, req), req);
3502 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003503 break;
3504
3505 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003506 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003507 break;
3508
3509 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003510 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003511 break;
3512 }
3513
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003514 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003515
3516unlock:
3517 mutex_unlock(&conn->chan_lock);
3518
3519 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003520}
3521
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003522static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003523{
3524 /* FCS is enabled only in ERTM or streaming mode, if one or both
3525 * sides request it.
3526 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003527 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003528 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003529 else if (!test_bit(CONF_NO_FCS_RECV, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003530 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003531}
3532
Al Viro88219a02007-07-29 00:17:25 -07003533static 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 -07003534{
3535 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3536 u16 dcid, flags;
3537 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003538 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003539 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003540
3541 dcid = __le16_to_cpu(req->dcid);
3542 flags = __le16_to_cpu(req->flags);
3543
3544 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3545
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003546 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003547 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003548 return -ENOENT;
3549
David S. Miller033b1142011-07-21 13:38:42 -07003550 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003551 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003552
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003553 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003554 rej.scid = cpu_to_le16(chan->scid);
3555 rej.dcid = cpu_to_le16(chan->dcid);
3556
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003557 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
3558 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003559 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003560 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003561
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003562 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003563 len = cmd_len - sizeof(*req);
Dan Rosenberg7ac28812011-06-24 08:38:05 -04003564 if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003565 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003566 l2cap_build_conf_rsp(chan, rsp,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003567 L2CAP_CONF_REJECT, flags), rsp);
3568 goto unlock;
3569 }
3570
3571 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003572 memcpy(chan->conf_req + chan->conf_len, req->data, len);
3573 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003574
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003575 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003576 /* Incomplete config. Send empty response. */
3577 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003578 l2cap_build_conf_rsp(chan, rsp,
Andrei Emeltchenko5325e5b2012-05-23 11:31:22 +03003579 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003580 goto unlock;
3581 }
3582
3583 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003584 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003585 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003586 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003587 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003588 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003589
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003590 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003591 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003592
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003593 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003594 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003595
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003596 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02003597 goto unlock;
3598
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003599 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003600 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003601
Mat Martineau105bdf92012-04-27 16:50:48 -07003602 if (chan->mode == L2CAP_MODE_ERTM ||
3603 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003604 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003605
Mat Martineau3c588192012-04-11 10:48:42 -07003606 if (err < 0)
3607 l2cap_send_disconn_req(chan->conn, chan, -err);
3608 else
3609 l2cap_chan_ready(chan);
3610
Marcel Holtmann876d9482007-10-20 13:35:42 +02003611 goto unlock;
3612 }
3613
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003614 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003615 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003616 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003617 l2cap_build_conf_req(chan, buf), buf);
3618 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003619 }
3620
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003621 /* Got Conf Rsp PENDING from remote side and asume we sent
3622 Conf Rsp PENDING in the code above */
3623 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
3624 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3625
3626 /* check compatibility */
3627
3628 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3629 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3630
3631 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003632 l2cap_build_conf_rsp(chan, rsp,
Andrei Emeltchenko5325e5b2012-05-23 11:31:22 +03003633 L2CAP_CONF_SUCCESS, flags), rsp);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003634 }
3635
Linus Torvalds1da177e2005-04-16 15:20:36 -07003636unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003637 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003638 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003639}
3640
3641static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3642{
3643 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3644 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003645 struct l2cap_chan *chan;
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003646 int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07003647 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003648
3649 scid = __le16_to_cpu(rsp->scid);
3650 flags = __le16_to_cpu(rsp->flags);
3651 result = __le16_to_cpu(rsp->result);
3652
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003653 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
3654 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003655
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003656 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003657 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003658 return 0;
3659
3660 switch (result) {
3661 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003662 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003663 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003664 break;
3665
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003666 case L2CAP_CONF_PENDING:
3667 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
3668
3669 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3670 char buf[64];
3671
3672 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3673 buf, &result);
3674 if (len < 0) {
3675 l2cap_send_disconn_req(conn, chan, ECONNRESET);
3676 goto done;
3677 }
3678
3679 /* check compatibility */
3680
3681 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3682 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3683
3684 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003685 l2cap_build_conf_rsp(chan, buf,
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003686 L2CAP_CONF_SUCCESS, 0x0000), buf);
3687 }
3688 goto done;
3689
Linus Torvalds1da177e2005-04-16 15:20:36 -07003690 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003691 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003692 char req[64];
3693
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003694 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003695 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003696 goto done;
3697 }
3698
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003699 /* throw out any old stored conf requests */
3700 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003701 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3702 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003703 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003704 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003705 goto done;
3706 }
3707
3708 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3709 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003710 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003711 if (result != L2CAP_CONF_SUCCESS)
3712 goto done;
3713 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003714 }
3715
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003716 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003717 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02003718
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003719 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003720 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003721 goto done;
3722 }
3723
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003724 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003725 goto done;
3726
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003727 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003728
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003729 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003730 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003731
Mat Martineau105bdf92012-04-27 16:50:48 -07003732 if (chan->mode == L2CAP_MODE_ERTM ||
3733 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003734 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003735
Mat Martineau3c588192012-04-11 10:48:42 -07003736 if (err < 0)
3737 l2cap_send_disconn_req(chan->conn, chan, -err);
3738 else
3739 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003740 }
3741
3742done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003743 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003744 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003745}
3746
3747static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3748{
3749 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3750 struct l2cap_disconn_rsp rsp;
3751 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003752 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003753 struct sock *sk;
3754
3755 scid = __le16_to_cpu(req->scid);
3756 dcid = __le16_to_cpu(req->dcid);
3757
3758 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3759
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003760 mutex_lock(&conn->chan_lock);
3761
3762 chan = __l2cap_get_chan_by_scid(conn, dcid);
3763 if (!chan) {
3764 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003765 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003766 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003767
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003768 l2cap_chan_lock(chan);
3769
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003770 sk = chan->sk;
3771
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003772 rsp.dcid = cpu_to_le16(chan->scid);
3773 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003774 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3775
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003776 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003777 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003778 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003779
Mat Martineau61d6ef32012-04-27 16:50:50 -07003780 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003781 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003782
3783 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003784
Gustavo Padovan80b98022012-05-27 22:27:51 -03003785 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003786 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003787
3788 mutex_unlock(&conn->chan_lock);
3789
Linus Torvalds1da177e2005-04-16 15:20:36 -07003790 return 0;
3791}
3792
3793static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3794{
3795 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3796 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003797 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003798
3799 scid = __le16_to_cpu(rsp->scid);
3800 dcid = __le16_to_cpu(rsp->dcid);
3801
3802 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3803
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003804 mutex_lock(&conn->chan_lock);
3805
3806 chan = __l2cap_get_chan_by_scid(conn, scid);
3807 if (!chan) {
3808 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003809 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003810 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003811
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003812 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003813
Mat Martineau61d6ef32012-04-27 16:50:50 -07003814 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003815 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003816
3817 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003818
Gustavo Padovan80b98022012-05-27 22:27:51 -03003819 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003820 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003821
3822 mutex_unlock(&conn->chan_lock);
3823
Linus Torvalds1da177e2005-04-16 15:20:36 -07003824 return 0;
3825}
3826
3827static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3828{
3829 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003830 u16 type;
3831
3832 type = __le16_to_cpu(req->type);
3833
3834 BT_DBG("type 0x%4.4x", type);
3835
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003836 if (type == L2CAP_IT_FEAT_MASK) {
3837 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003838 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003839 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003840 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
3841 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03003842 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003843 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3844 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003845 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003846 feat_mask |= L2CAP_FEAT_EXT_FLOW
3847 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003848
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003849 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003850 l2cap_send_cmd(conn, cmd->ident,
3851 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003852 } else if (type == L2CAP_IT_FIXED_CHAN) {
3853 u8 buf[12];
3854 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07003855
3856 if (enable_hs)
3857 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
3858 else
3859 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
3860
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003861 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3862 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03003863 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003864 l2cap_send_cmd(conn, cmd->ident,
3865 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003866 } else {
3867 struct l2cap_info_rsp rsp;
3868 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003869 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003870 l2cap_send_cmd(conn, cmd->ident,
3871 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3872 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003873
3874 return 0;
3875}
3876
3877static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3878{
3879 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3880 u16 type, result;
3881
3882 type = __le16_to_cpu(rsp->type);
3883 result = __le16_to_cpu(rsp->result);
3884
3885 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3886
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02003887 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
3888 if (cmd->ident != conn->info_ident ||
3889 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
3890 return 0;
3891
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003892 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003893
Ville Tervoadb08ed2010-08-04 09:43:33 +03003894 if (result != L2CAP_IR_SUCCESS) {
3895 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3896 conn->info_ident = 0;
3897
3898 l2cap_conn_start(conn);
3899
3900 return 0;
3901 }
3902
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003903 switch (type) {
3904 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07003905 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003906
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003907 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003908 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003909 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003910
3911 conn->info_ident = l2cap_get_ident(conn);
3912
3913 l2cap_send_cmd(conn, conn->info_ident,
3914 L2CAP_INFO_REQ, sizeof(req), &req);
3915 } else {
3916 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3917 conn->info_ident = 0;
3918
3919 l2cap_conn_start(conn);
3920 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003921 break;
3922
3923 case L2CAP_IT_FIXED_CHAN:
3924 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01003925 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003926 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003927
3928 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003929 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003930 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003931
Linus Torvalds1da177e2005-04-16 15:20:36 -07003932 return 0;
3933}
3934
Mat Martineauf94ff6f2011-11-02 16:18:32 -07003935static inline int l2cap_create_channel_req(struct l2cap_conn *conn,
3936 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3937 void *data)
3938{
3939 struct l2cap_create_chan_req *req = data;
3940 struct l2cap_create_chan_rsp rsp;
3941 u16 psm, scid;
3942
3943 if (cmd_len != sizeof(*req))
3944 return -EPROTO;
3945
3946 if (!enable_hs)
3947 return -EINVAL;
3948
3949 psm = le16_to_cpu(req->psm);
3950 scid = le16_to_cpu(req->scid);
3951
3952 BT_DBG("psm %d, scid %d, amp_id %d", psm, scid, req->amp_id);
3953
3954 /* Placeholder: Always reject */
3955 rsp.dcid = 0;
3956 rsp.scid = cpu_to_le16(scid);
Andrei Emeltchenko8ce0c492012-03-12 12:13:09 +02003957 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
3958 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07003959
3960 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
3961 sizeof(rsp), &rsp);
3962
3963 return 0;
3964}
3965
3966static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn,
3967 struct l2cap_cmd_hdr *cmd, void *data)
3968{
3969 BT_DBG("conn %p", conn);
3970
3971 return l2cap_connect_rsp(conn, cmd, data);
3972}
3973
Mat Martineau8d5a04a2011-11-02 16:18:35 -07003974static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident,
3975 u16 icid, u16 result)
3976{
3977 struct l2cap_move_chan_rsp rsp;
3978
3979 BT_DBG("icid %d, result %d", icid, result);
3980
3981 rsp.icid = cpu_to_le16(icid);
3982 rsp.result = cpu_to_le16(result);
3983
3984 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_RSP, sizeof(rsp), &rsp);
3985}
3986
3987static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn,
3988 struct l2cap_chan *chan, u16 icid, u16 result)
3989{
3990 struct l2cap_move_chan_cfm cfm;
3991 u8 ident;
3992
3993 BT_DBG("icid %d, result %d", icid, result);
3994
3995 ident = l2cap_get_ident(conn);
3996 if (chan)
3997 chan->ident = ident;
3998
3999 cfm.icid = cpu_to_le16(icid);
4000 cfm.result = cpu_to_le16(result);
4001
4002 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM, sizeof(cfm), &cfm);
4003}
4004
4005static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
4006 u16 icid)
4007{
4008 struct l2cap_move_chan_cfm_rsp rsp;
4009
4010 BT_DBG("icid %d", icid);
4011
4012 rsp.icid = cpu_to_le16(icid);
4013 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4014}
4015
4016static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
4017 struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data)
4018{
4019 struct l2cap_move_chan_req *req = data;
4020 u16 icid = 0;
4021 u16 result = L2CAP_MR_NOT_ALLOWED;
4022
4023 if (cmd_len != sizeof(*req))
4024 return -EPROTO;
4025
4026 icid = le16_to_cpu(req->icid);
4027
4028 BT_DBG("icid %d, dest_amp_id %d", icid, req->dest_amp_id);
4029
4030 if (!enable_hs)
4031 return -EINVAL;
4032
4033 /* Placeholder: Always refuse */
4034 l2cap_send_move_chan_rsp(conn, cmd->ident, icid, result);
4035
4036 return 0;
4037}
4038
4039static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn,
4040 struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data)
4041{
4042 struct l2cap_move_chan_rsp *rsp = data;
4043 u16 icid, result;
4044
4045 if (cmd_len != sizeof(*rsp))
4046 return -EPROTO;
4047
4048 icid = le16_to_cpu(rsp->icid);
4049 result = le16_to_cpu(rsp->result);
4050
4051 BT_DBG("icid %d, result %d", icid, result);
4052
4053 /* Placeholder: Always unconfirmed */
4054 l2cap_send_move_chan_cfm(conn, NULL, icid, L2CAP_MC_UNCONFIRMED);
4055
4056 return 0;
4057}
4058
4059static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn,
4060 struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data)
4061{
4062 struct l2cap_move_chan_cfm *cfm = data;
4063 u16 icid, result;
4064
4065 if (cmd_len != sizeof(*cfm))
4066 return -EPROTO;
4067
4068 icid = le16_to_cpu(cfm->icid);
4069 result = le16_to_cpu(cfm->result);
4070
4071 BT_DBG("icid %d, result %d", icid, result);
4072
4073 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4074
4075 return 0;
4076}
4077
4078static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
4079 struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data)
4080{
4081 struct l2cap_move_chan_cfm_rsp *rsp = data;
4082 u16 icid;
4083
4084 if (cmd_len != sizeof(*rsp))
4085 return -EPROTO;
4086
4087 icid = le16_to_cpu(rsp->icid);
4088
4089 BT_DBG("icid %d", icid);
4090
4091 return 0;
4092}
4093
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004094static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Claudio Takahaside731152011-02-11 19:28:55 -02004095 u16 to_multiplier)
4096{
4097 u16 max_latency;
4098
4099 if (min > max || min < 6 || max > 3200)
4100 return -EINVAL;
4101
4102 if (to_multiplier < 10 || to_multiplier > 3200)
4103 return -EINVAL;
4104
4105 if (max >= to_multiplier * 8)
4106 return -EINVAL;
4107
4108 max_latency = (to_multiplier * 8 / max) - 1;
4109 if (latency > 499 || latency > max_latency)
4110 return -EINVAL;
4111
4112 return 0;
4113}
4114
4115static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
4116 struct l2cap_cmd_hdr *cmd, u8 *data)
4117{
4118 struct hci_conn *hcon = conn->hcon;
4119 struct l2cap_conn_param_update_req *req;
4120 struct l2cap_conn_param_update_rsp rsp;
4121 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004122 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02004123
4124 if (!(hcon->link_mode & HCI_LM_MASTER))
4125 return -EINVAL;
4126
4127 cmd_len = __le16_to_cpu(cmd->len);
4128 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
4129 return -EPROTO;
4130
4131 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004132 min = __le16_to_cpu(req->min);
4133 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02004134 latency = __le16_to_cpu(req->latency);
4135 to_multiplier = __le16_to_cpu(req->to_multiplier);
4136
4137 BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
4138 min, max, latency, to_multiplier);
4139
4140 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004141
4142 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
4143 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004144 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004145 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004146 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004147
4148 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
4149 sizeof(rsp), &rsp);
4150
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004151 if (!err)
4152 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
4153
Claudio Takahaside731152011-02-11 19:28:55 -02004154 return 0;
4155}
4156
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004157static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
4158 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
4159{
4160 int err = 0;
4161
4162 switch (cmd->code) {
4163 case L2CAP_COMMAND_REJ:
4164 l2cap_command_rej(conn, cmd, data);
4165 break;
4166
4167 case L2CAP_CONN_REQ:
4168 err = l2cap_connect_req(conn, cmd, data);
4169 break;
4170
4171 case L2CAP_CONN_RSP:
4172 err = l2cap_connect_rsp(conn, cmd, data);
4173 break;
4174
4175 case L2CAP_CONF_REQ:
4176 err = l2cap_config_req(conn, cmd, cmd_len, data);
4177 break;
4178
4179 case L2CAP_CONF_RSP:
4180 err = l2cap_config_rsp(conn, cmd, data);
4181 break;
4182
4183 case L2CAP_DISCONN_REQ:
4184 err = l2cap_disconnect_req(conn, cmd, data);
4185 break;
4186
4187 case L2CAP_DISCONN_RSP:
4188 err = l2cap_disconnect_rsp(conn, cmd, data);
4189 break;
4190
4191 case L2CAP_ECHO_REQ:
4192 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
4193 break;
4194
4195 case L2CAP_ECHO_RSP:
4196 break;
4197
4198 case L2CAP_INFO_REQ:
4199 err = l2cap_information_req(conn, cmd, data);
4200 break;
4201
4202 case L2CAP_INFO_RSP:
4203 err = l2cap_information_rsp(conn, cmd, data);
4204 break;
4205
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004206 case L2CAP_CREATE_CHAN_REQ:
4207 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
4208 break;
4209
4210 case L2CAP_CREATE_CHAN_RSP:
4211 err = l2cap_create_channel_rsp(conn, cmd, data);
4212 break;
4213
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004214 case L2CAP_MOVE_CHAN_REQ:
4215 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
4216 break;
4217
4218 case L2CAP_MOVE_CHAN_RSP:
4219 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
4220 break;
4221
4222 case L2CAP_MOVE_CHAN_CFM:
4223 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
4224 break;
4225
4226 case L2CAP_MOVE_CHAN_CFM_RSP:
4227 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
4228 break;
4229
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004230 default:
4231 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
4232 err = -EINVAL;
4233 break;
4234 }
4235
4236 return err;
4237}
4238
4239static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
4240 struct l2cap_cmd_hdr *cmd, u8 *data)
4241{
4242 switch (cmd->code) {
4243 case L2CAP_COMMAND_REJ:
4244 return 0;
4245
4246 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02004247 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004248
4249 case L2CAP_CONN_PARAM_UPDATE_RSP:
4250 return 0;
4251
4252 default:
4253 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
4254 return -EINVAL;
4255 }
4256}
4257
4258static inline void l2cap_sig_channel(struct l2cap_conn *conn,
4259 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004260{
4261 u8 *data = skb->data;
4262 int len = skb->len;
4263 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004264 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004265
4266 l2cap_raw_recv(conn, skb);
4267
4268 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07004269 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004270 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
4271 data += L2CAP_CMD_HDR_SIZE;
4272 len -= L2CAP_CMD_HDR_SIZE;
4273
Al Viro88219a02007-07-29 00:17:25 -07004274 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004275
Al Viro88219a02007-07-29 00:17:25 -07004276 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 -07004277
Al Viro88219a02007-07-29 00:17:25 -07004278 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004279 BT_DBG("corrupted command");
4280 break;
4281 }
4282
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004283 if (conn->hcon->type == LE_LINK)
4284 err = l2cap_le_sig_cmd(conn, &cmd, data);
4285 else
4286 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004287
4288 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004289 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03004290
4291 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004292
4293 /* FIXME: Map err to a valid reason */
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004294 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004295 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
4296 }
4297
Al Viro88219a02007-07-29 00:17:25 -07004298 data += cmd_len;
4299 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004300 }
4301
4302 kfree_skb(skb);
4303}
4304
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004305static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004306{
4307 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03004308 int hdr_size;
4309
4310 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
4311 hdr_size = L2CAP_EXT_HDR_SIZE;
4312 else
4313 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004314
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004315 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004316 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004317 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
4318 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
4319
4320 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03004321 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004322 }
4323 return 0;
4324}
4325
Mat Martineau6ea00482012-05-17 20:53:52 -07004326static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004327{
Mat Martineaue31f7632012-05-17 20:53:41 -07004328 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004329
Mat Martineaue31f7632012-05-17 20:53:41 -07004330 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004331
Mat Martineaue31f7632012-05-17 20:53:41 -07004332 memset(&control, 0, sizeof(control));
4333 control.sframe = 1;
4334 control.final = 1;
4335 control.reqseq = chan->buffer_seq;
4336 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004337
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004338 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07004339 control.super = L2CAP_SUPER_RNR;
4340 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004341 }
4342
Mat Martineaue31f7632012-05-17 20:53:41 -07004343 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
4344 chan->unacked_frames > 0)
4345 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004346
Mat Martineaue31f7632012-05-17 20:53:41 -07004347 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03004348 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004349
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004350 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07004351 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
4352 /* F-bit wasn't sent in an s-frame or i-frame yet, so
4353 * send it now.
4354 */
4355 control.super = L2CAP_SUPER_RR;
4356 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004357 }
4358}
4359
Mat Martineau84084a32011-07-22 14:54:00 -07004360static void append_skb_frag(struct sk_buff *skb,
4361 struct sk_buff *new_frag, struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004362{
Mat Martineau84084a32011-07-22 14:54:00 -07004363 /* skb->len reflects data in skb as well as all fragments
4364 * skb->data_len reflects only data in fragments
4365 */
4366 if (!skb_has_frag_list(skb))
4367 skb_shinfo(skb)->frag_list = new_frag;
4368
4369 new_frag->next = NULL;
4370
4371 (*last_frag)->next = new_frag;
4372 *last_frag = new_frag;
4373
4374 skb->len += new_frag->len;
4375 skb->data_len += new_frag->len;
4376 skb->truesize += new_frag->truesize;
4377}
4378
Mat Martineau4b51dae92012-05-17 20:53:37 -07004379static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
4380 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07004381{
4382 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004383
Mat Martineau4b51dae92012-05-17 20:53:37 -07004384 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004385 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07004386 if (chan->sdu)
4387 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004388
Gustavo Padovan80b98022012-05-27 22:27:51 -03004389 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07004390 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004391
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004392 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07004393 if (chan->sdu)
4394 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004395
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004396 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004397 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004398
Mat Martineau84084a32011-07-22 14:54:00 -07004399 if (chan->sdu_len > chan->imtu) {
4400 err = -EMSGSIZE;
4401 break;
4402 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004403
Mat Martineau84084a32011-07-22 14:54:00 -07004404 if (skb->len >= chan->sdu_len)
4405 break;
4406
4407 chan->sdu = skb;
4408 chan->sdu_last_frag = skb;
4409
4410 skb = NULL;
4411 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004412 break;
4413
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004414 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004415 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004416 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004417
Mat Martineau84084a32011-07-22 14:54:00 -07004418 append_skb_frag(chan->sdu, skb,
4419 &chan->sdu_last_frag);
4420 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004421
Mat Martineau84084a32011-07-22 14:54:00 -07004422 if (chan->sdu->len >= chan->sdu_len)
4423 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004424
Mat Martineau84084a32011-07-22 14:54:00 -07004425 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004426 break;
4427
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004428 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004429 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004430 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004431
Mat Martineau84084a32011-07-22 14:54:00 -07004432 append_skb_frag(chan->sdu, skb,
4433 &chan->sdu_last_frag);
4434 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004435
Mat Martineau84084a32011-07-22 14:54:00 -07004436 if (chan->sdu->len != chan->sdu_len)
4437 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004438
Gustavo Padovan80b98022012-05-27 22:27:51 -03004439 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004440
Mat Martineau84084a32011-07-22 14:54:00 -07004441 if (!err) {
4442 /* Reassembly complete */
4443 chan->sdu = NULL;
4444 chan->sdu_last_frag = NULL;
4445 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004446 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004447 break;
4448 }
4449
Mat Martineau84084a32011-07-22 14:54:00 -07004450 if (err) {
4451 kfree_skb(skb);
4452 kfree_skb(chan->sdu);
4453 chan->sdu = NULL;
4454 chan->sdu_last_frag = NULL;
4455 chan->sdu_len = 0;
4456 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004457
Mat Martineau84084a32011-07-22 14:54:00 -07004458 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004459}
4460
Mat Martineaue3281402011-07-07 09:39:02 -07004461void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03004462{
Mat Martineau61aa4f52012-05-17 20:53:40 -07004463 u8 event;
4464
4465 if (chan->mode != L2CAP_MODE_ERTM)
4466 return;
4467
4468 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03004469 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004470}
4471
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004472static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
4473{
Mat Martineau63838722012-05-17 20:53:45 -07004474 int err = 0;
4475 /* Pass sequential frames to l2cap_reassemble_sdu()
4476 * until a gap is encountered.
4477 */
4478
4479 BT_DBG("chan %p", chan);
4480
4481 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4482 struct sk_buff *skb;
4483 BT_DBG("Searching for skb with txseq %d (queue len %d)",
4484 chan->buffer_seq, skb_queue_len(&chan->srej_q));
4485
4486 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
4487
4488 if (!skb)
4489 break;
4490
4491 skb_unlink(skb, &chan->srej_q);
4492 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
4493 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
4494 if (err)
4495 break;
4496 }
4497
4498 if (skb_queue_empty(&chan->srej_q)) {
4499 chan->rx_state = L2CAP_RX_STATE_RECV;
4500 l2cap_send_ack(chan);
4501 }
4502
4503 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004504}
4505
4506static void l2cap_handle_srej(struct l2cap_chan *chan,
4507 struct l2cap_ctrl *control)
4508{
Mat Martineauf80842a2012-05-17 20:53:46 -07004509 struct sk_buff *skb;
4510
4511 BT_DBG("chan %p, control %p", chan, control);
4512
4513 if (control->reqseq == chan->next_tx_seq) {
4514 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4515 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4516 return;
4517 }
4518
4519 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4520
4521 if (skb == NULL) {
4522 BT_DBG("Seq %d not available for retransmission",
4523 control->reqseq);
4524 return;
4525 }
4526
4527 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
4528 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4529 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4530 return;
4531 }
4532
4533 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4534
4535 if (control->poll) {
4536 l2cap_pass_to_tx(chan, control);
4537
4538 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4539 l2cap_retransmit(chan, control);
4540 l2cap_ertm_send(chan);
4541
4542 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4543 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4544 chan->srej_save_reqseq = control->reqseq;
4545 }
4546 } else {
4547 l2cap_pass_to_tx_fbit(chan, control);
4548
4549 if (control->final) {
4550 if (chan->srej_save_reqseq != control->reqseq ||
4551 !test_and_clear_bit(CONN_SREJ_ACT,
4552 &chan->conn_state))
4553 l2cap_retransmit(chan, control);
4554 } else {
4555 l2cap_retransmit(chan, control);
4556 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4557 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4558 chan->srej_save_reqseq = control->reqseq;
4559 }
4560 }
4561 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004562}
4563
4564static void l2cap_handle_rej(struct l2cap_chan *chan,
4565 struct l2cap_ctrl *control)
4566{
Mat Martineaufcd289d2012-05-17 20:53:47 -07004567 struct sk_buff *skb;
4568
4569 BT_DBG("chan %p, control %p", chan, control);
4570
4571 if (control->reqseq == chan->next_tx_seq) {
4572 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4573 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4574 return;
4575 }
4576
4577 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4578
4579 if (chan->max_tx && skb &&
4580 bt_cb(skb)->control.retries >= chan->max_tx) {
4581 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4582 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4583 return;
4584 }
4585
4586 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4587
4588 l2cap_pass_to_tx(chan, control);
4589
4590 if (control->final) {
4591 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
4592 l2cap_retransmit_all(chan, control);
4593 } else {
4594 l2cap_retransmit_all(chan, control);
4595 l2cap_ertm_send(chan);
4596 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
4597 set_bit(CONN_REJ_ACT, &chan->conn_state);
4598 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004599}
4600
Mat Martineau4b51dae92012-05-17 20:53:37 -07004601static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
4602{
4603 BT_DBG("chan %p, txseq %d", chan, txseq);
4604
4605 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
4606 chan->expected_tx_seq);
4607
4608 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
4609 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4610 chan->tx_win) {
4611 /* See notes below regarding "double poll" and
4612 * invalid packets.
4613 */
4614 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4615 BT_DBG("Invalid/Ignore - after SREJ");
4616 return L2CAP_TXSEQ_INVALID_IGNORE;
4617 } else {
4618 BT_DBG("Invalid - in window after SREJ sent");
4619 return L2CAP_TXSEQ_INVALID;
4620 }
4621 }
4622
4623 if (chan->srej_list.head == txseq) {
4624 BT_DBG("Expected SREJ");
4625 return L2CAP_TXSEQ_EXPECTED_SREJ;
4626 }
4627
4628 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
4629 BT_DBG("Duplicate SREJ - txseq already stored");
4630 return L2CAP_TXSEQ_DUPLICATE_SREJ;
4631 }
4632
4633 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
4634 BT_DBG("Unexpected SREJ - not requested");
4635 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
4636 }
4637 }
4638
4639 if (chan->expected_tx_seq == txseq) {
4640 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4641 chan->tx_win) {
4642 BT_DBG("Invalid - txseq outside tx window");
4643 return L2CAP_TXSEQ_INVALID;
4644 } else {
4645 BT_DBG("Expected");
4646 return L2CAP_TXSEQ_EXPECTED;
4647 }
4648 }
4649
4650 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
4651 __seq_offset(chan, chan->expected_tx_seq,
4652 chan->last_acked_seq)){
4653 BT_DBG("Duplicate - expected_tx_seq later than txseq");
4654 return L2CAP_TXSEQ_DUPLICATE;
4655 }
4656
4657 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
4658 /* A source of invalid packets is a "double poll" condition,
4659 * where delays cause us to send multiple poll packets. If
4660 * the remote stack receives and processes both polls,
4661 * sequence numbers can wrap around in such a way that a
4662 * resent frame has a sequence number that looks like new data
4663 * with a sequence gap. This would trigger an erroneous SREJ
4664 * request.
4665 *
4666 * Fortunately, this is impossible with a tx window that's
4667 * less than half of the maximum sequence number, which allows
4668 * invalid frames to be safely ignored.
4669 *
4670 * With tx window sizes greater than half of the tx window
4671 * maximum, the frame is invalid and cannot be ignored. This
4672 * causes a disconnect.
4673 */
4674
4675 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4676 BT_DBG("Invalid/Ignore - txseq outside tx window");
4677 return L2CAP_TXSEQ_INVALID_IGNORE;
4678 } else {
4679 BT_DBG("Invalid - txseq outside tx window");
4680 return L2CAP_TXSEQ_INVALID;
4681 }
4682 } else {
4683 BT_DBG("Unexpected - txseq indicates missing frames");
4684 return L2CAP_TXSEQ_UNEXPECTED;
4685 }
4686}
4687
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004688static int l2cap_rx_state_recv(struct l2cap_chan *chan,
4689 struct l2cap_ctrl *control,
4690 struct sk_buff *skb, u8 event)
4691{
4692 int err = 0;
4693 bool skb_in_use = 0;
4694
4695 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4696 event);
4697
4698 switch (event) {
4699 case L2CAP_EV_RECV_IFRAME:
4700 switch (l2cap_classify_txseq(chan, control->txseq)) {
4701 case L2CAP_TXSEQ_EXPECTED:
4702 l2cap_pass_to_tx(chan, control);
4703
4704 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4705 BT_DBG("Busy, discarding expected seq %d",
4706 control->txseq);
4707 break;
4708 }
4709
4710 chan->expected_tx_seq = __next_seq(chan,
4711 control->txseq);
4712
4713 chan->buffer_seq = chan->expected_tx_seq;
4714 skb_in_use = 1;
4715
4716 err = l2cap_reassemble_sdu(chan, skb, control);
4717 if (err)
4718 break;
4719
4720 if (control->final) {
4721 if (!test_and_clear_bit(CONN_REJ_ACT,
4722 &chan->conn_state)) {
4723 control->final = 0;
4724 l2cap_retransmit_all(chan, control);
4725 l2cap_ertm_send(chan);
4726 }
4727 }
4728
4729 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
4730 l2cap_send_ack(chan);
4731 break;
4732 case L2CAP_TXSEQ_UNEXPECTED:
4733 l2cap_pass_to_tx(chan, control);
4734
4735 /* Can't issue SREJ frames in the local busy state.
4736 * Drop this frame, it will be seen as missing
4737 * when local busy is exited.
4738 */
4739 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4740 BT_DBG("Busy, discarding unexpected seq %d",
4741 control->txseq);
4742 break;
4743 }
4744
4745 /* There was a gap in the sequence, so an SREJ
4746 * must be sent for each missing frame. The
4747 * current frame is stored for later use.
4748 */
4749 skb_queue_tail(&chan->srej_q, skb);
4750 skb_in_use = 1;
4751 BT_DBG("Queued %p (queue len %d)", skb,
4752 skb_queue_len(&chan->srej_q));
4753
4754 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
4755 l2cap_seq_list_clear(&chan->srej_list);
4756 l2cap_send_srej(chan, control->txseq);
4757
4758 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
4759 break;
4760 case L2CAP_TXSEQ_DUPLICATE:
4761 l2cap_pass_to_tx(chan, control);
4762 break;
4763 case L2CAP_TXSEQ_INVALID_IGNORE:
4764 break;
4765 case L2CAP_TXSEQ_INVALID:
4766 default:
4767 l2cap_send_disconn_req(chan->conn, chan,
4768 ECONNRESET);
4769 break;
4770 }
4771 break;
4772 case L2CAP_EV_RECV_RR:
4773 l2cap_pass_to_tx(chan, control);
4774 if (control->final) {
4775 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4776
4777 if (!test_and_clear_bit(CONN_REJ_ACT,
4778 &chan->conn_state)) {
4779 control->final = 0;
4780 l2cap_retransmit_all(chan, control);
4781 }
4782
4783 l2cap_ertm_send(chan);
4784 } else if (control->poll) {
4785 l2cap_send_i_or_rr_or_rnr(chan);
4786 } else {
4787 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4788 &chan->conn_state) &&
4789 chan->unacked_frames)
4790 __set_retrans_timer(chan);
4791
4792 l2cap_ertm_send(chan);
4793 }
4794 break;
4795 case L2CAP_EV_RECV_RNR:
4796 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4797 l2cap_pass_to_tx(chan, control);
4798 if (control && control->poll) {
4799 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4800 l2cap_send_rr_or_rnr(chan, 0);
4801 }
4802 __clear_retrans_timer(chan);
4803 l2cap_seq_list_clear(&chan->retrans_list);
4804 break;
4805 case L2CAP_EV_RECV_REJ:
4806 l2cap_handle_rej(chan, control);
4807 break;
4808 case L2CAP_EV_RECV_SREJ:
4809 l2cap_handle_srej(chan, control);
4810 break;
4811 default:
4812 break;
4813 }
4814
4815 if (skb && !skb_in_use) {
4816 BT_DBG("Freeing %p", skb);
4817 kfree_skb(skb);
4818 }
4819
4820 return err;
4821}
4822
4823static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
4824 struct l2cap_ctrl *control,
4825 struct sk_buff *skb, u8 event)
4826{
4827 int err = 0;
4828 u16 txseq = control->txseq;
4829 bool skb_in_use = 0;
4830
4831 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4832 event);
4833
4834 switch (event) {
4835 case L2CAP_EV_RECV_IFRAME:
4836 switch (l2cap_classify_txseq(chan, txseq)) {
4837 case L2CAP_TXSEQ_EXPECTED:
4838 /* Keep frame for reassembly later */
4839 l2cap_pass_to_tx(chan, control);
4840 skb_queue_tail(&chan->srej_q, skb);
4841 skb_in_use = 1;
4842 BT_DBG("Queued %p (queue len %d)", skb,
4843 skb_queue_len(&chan->srej_q));
4844
4845 chan->expected_tx_seq = __next_seq(chan, txseq);
4846 break;
4847 case L2CAP_TXSEQ_EXPECTED_SREJ:
4848 l2cap_seq_list_pop(&chan->srej_list);
4849
4850 l2cap_pass_to_tx(chan, control);
4851 skb_queue_tail(&chan->srej_q, skb);
4852 skb_in_use = 1;
4853 BT_DBG("Queued %p (queue len %d)", skb,
4854 skb_queue_len(&chan->srej_q));
4855
4856 err = l2cap_rx_queued_iframes(chan);
4857 if (err)
4858 break;
4859
4860 break;
4861 case L2CAP_TXSEQ_UNEXPECTED:
4862 /* Got a frame that can't be reassembled yet.
4863 * Save it for later, and send SREJs to cover
4864 * the missing frames.
4865 */
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 l2cap_pass_to_tx(chan, control);
4872 l2cap_send_srej(chan, control->txseq);
4873 break;
4874 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
4875 /* This frame was requested with an SREJ, but
4876 * some expected retransmitted frames are
4877 * missing. Request retransmission of missing
4878 * SREJ'd frames.
4879 */
4880 skb_queue_tail(&chan->srej_q, skb);
4881 skb_in_use = 1;
4882 BT_DBG("Queued %p (queue len %d)", skb,
4883 skb_queue_len(&chan->srej_q));
4884
4885 l2cap_pass_to_tx(chan, control);
4886 l2cap_send_srej_list(chan, control->txseq);
4887 break;
4888 case L2CAP_TXSEQ_DUPLICATE_SREJ:
4889 /* We've already queued this frame. Drop this copy. */
4890 l2cap_pass_to_tx(chan, control);
4891 break;
4892 case L2CAP_TXSEQ_DUPLICATE:
4893 /* Expecting a later sequence number, so this frame
4894 * was already received. Ignore it completely.
4895 */
4896 break;
4897 case L2CAP_TXSEQ_INVALID_IGNORE:
4898 break;
4899 case L2CAP_TXSEQ_INVALID:
4900 default:
4901 l2cap_send_disconn_req(chan->conn, chan,
4902 ECONNRESET);
4903 break;
4904 }
4905 break;
4906 case L2CAP_EV_RECV_RR:
4907 l2cap_pass_to_tx(chan, control);
4908 if (control->final) {
4909 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4910
4911 if (!test_and_clear_bit(CONN_REJ_ACT,
4912 &chan->conn_state)) {
4913 control->final = 0;
4914 l2cap_retransmit_all(chan, control);
4915 }
4916
4917 l2cap_ertm_send(chan);
4918 } else if (control->poll) {
4919 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4920 &chan->conn_state) &&
4921 chan->unacked_frames) {
4922 __set_retrans_timer(chan);
4923 }
4924
4925 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4926 l2cap_send_srej_tail(chan);
4927 } else {
4928 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4929 &chan->conn_state) &&
4930 chan->unacked_frames)
4931 __set_retrans_timer(chan);
4932
4933 l2cap_send_ack(chan);
4934 }
4935 break;
4936 case L2CAP_EV_RECV_RNR:
4937 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4938 l2cap_pass_to_tx(chan, control);
4939 if (control->poll) {
4940 l2cap_send_srej_tail(chan);
4941 } else {
4942 struct l2cap_ctrl rr_control;
4943 memset(&rr_control, 0, sizeof(rr_control));
4944 rr_control.sframe = 1;
4945 rr_control.super = L2CAP_SUPER_RR;
4946 rr_control.reqseq = chan->buffer_seq;
4947 l2cap_send_sframe(chan, &rr_control);
4948 }
4949
4950 break;
4951 case L2CAP_EV_RECV_REJ:
4952 l2cap_handle_rej(chan, control);
4953 break;
4954 case L2CAP_EV_RECV_SREJ:
4955 l2cap_handle_srej(chan, control);
4956 break;
4957 }
4958
4959 if (skb && !skb_in_use) {
4960 BT_DBG("Freeing %p", skb);
4961 kfree_skb(skb);
4962 }
4963
4964 return err;
4965}
4966
4967static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
4968{
4969 /* Make sure reqseq is for a packet that has been sent but not acked */
4970 u16 unacked;
4971
4972 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
4973 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
4974}
4975
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07004976static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
4977 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03004978{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004979 int err = 0;
4980
4981 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
4982 control, skb, event, chan->rx_state);
4983
4984 if (__valid_reqseq(chan, control->reqseq)) {
4985 switch (chan->rx_state) {
4986 case L2CAP_RX_STATE_RECV:
4987 err = l2cap_rx_state_recv(chan, control, skb, event);
4988 break;
4989 case L2CAP_RX_STATE_SREJ_SENT:
4990 err = l2cap_rx_state_srej_sent(chan, control, skb,
4991 event);
4992 break;
4993 default:
4994 /* shut it down */
4995 break;
4996 }
4997 } else {
4998 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
4999 control->reqseq, chan->next_tx_seq,
5000 chan->expected_ack_seq);
5001 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
5002 }
5003
5004 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005005}
5006
5007static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5008 struct sk_buff *skb)
5009{
Mat Martineau4b51dae92012-05-17 20:53:37 -07005010 int err = 0;
5011
5012 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
5013 chan->rx_state);
5014
5015 if (l2cap_classify_txseq(chan, control->txseq) ==
5016 L2CAP_TXSEQ_EXPECTED) {
5017 l2cap_pass_to_tx(chan, control);
5018
5019 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
5020 __next_seq(chan, chan->buffer_seq));
5021
5022 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5023
5024 l2cap_reassemble_sdu(chan, skb, control);
5025 } else {
5026 if (chan->sdu) {
5027 kfree_skb(chan->sdu);
5028 chan->sdu = NULL;
5029 }
5030 chan->sdu_last_frag = NULL;
5031 chan->sdu_len = 0;
5032
5033 if (skb) {
5034 BT_DBG("Freeing %p", skb);
5035 kfree_skb(skb);
5036 }
5037 }
5038
5039 chan->last_acked_seq = control->txseq;
5040 chan->expected_tx_seq = __next_seq(chan, control->txseq);
5041
5042 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005043}
5044
5045static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
5046{
5047 struct l2cap_ctrl *control = &bt_cb(skb)->control;
5048 u16 len;
5049 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005050
Mat Martineaub76bbd62012-04-11 10:48:43 -07005051 __unpack_control(chan, skb);
5052
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005053 len = skb->len;
5054
5055 /*
5056 * We can just drop the corrupted I-frame here.
5057 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005058 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005059 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005060 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005061 goto drop;
5062
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005063 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005064 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005065
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005066 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005067 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005068
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005069 if (len > chan->mps) {
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005070 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005071 goto drop;
5072 }
5073
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005074 if (!control->sframe) {
5075 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005076
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005077 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
5078 control->sar, control->reqseq, control->final,
5079 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03005080
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005081 /* Validate F-bit - F=0 always valid, F=1 only
5082 * valid in TX WAIT_F
5083 */
5084 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005085 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005086
5087 if (chan->mode != L2CAP_MODE_STREAMING) {
5088 event = L2CAP_EV_RECV_IFRAME;
5089 err = l2cap_rx(chan, control, skb, event);
5090 } else {
5091 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005092 }
5093
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005094 if (err)
5095 l2cap_send_disconn_req(chan->conn, chan,
5096 ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005097 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005098 const u8 rx_func_to_event[4] = {
5099 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
5100 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
5101 };
5102
5103 /* Only I-frames are expected in streaming mode */
5104 if (chan->mode == L2CAP_MODE_STREAMING)
5105 goto drop;
5106
5107 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
5108 control->reqseq, control->final, control->poll,
5109 control->super);
5110
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005111 if (len != 0) {
5112 BT_ERR("%d", len);
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005113 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005114 goto drop;
5115 }
5116
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005117 /* Validate F and P bits */
5118 if (control->final && (control->poll ||
5119 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
5120 goto drop;
5121
5122 event = rx_func_to_event[control->super];
5123 if (l2cap_rx(chan, control, skb, event))
5124 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005125 }
5126
5127 return 0;
5128
5129drop:
5130 kfree_skb(skb);
5131 return 0;
5132}
5133
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005134static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
5135 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005136{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005137 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005138
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03005139 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005140 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005141 if (cid == L2CAP_CID_A2MP) {
5142 chan = a2mp_channel_create(conn, skb);
5143 if (!chan) {
5144 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005145 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005146 }
5147
5148 l2cap_chan_lock(chan);
5149 } else {
5150 BT_DBG("unknown cid 0x%4.4x", cid);
5151 /* Drop packet and return */
5152 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005153 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005154 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005155 }
5156
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03005157 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005158
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005159 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005160 goto drop;
5161
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005162 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005163 case L2CAP_MODE_BASIC:
5164 /* If socket recv buffers overflows we drop data here
5165 * which is *bad* because L2CAP has to be reliable.
5166 * But we don't have any other choice. L2CAP doesn't
5167 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005168
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005169 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005170 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005171
Gustavo Padovan80b98022012-05-27 22:27:51 -03005172 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005173 goto done;
5174 break;
5175
5176 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005177 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005178 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005179 goto done;
5180
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005181 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005182 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005183 break;
5184 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005185
5186drop:
5187 kfree_skb(skb);
5188
5189done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005190 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005191}
5192
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03005193static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
5194 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005195{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005196 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005197
Ido Yarivc2287682012-04-20 15:46:07 -03005198 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005199 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005200 goto drop;
5201
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005202 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005203
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005204 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005205 goto drop;
5206
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005207 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005208 goto drop;
5209
Gustavo Padovan80b98022012-05-27 22:27:51 -03005210 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03005211 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005212
5213drop:
5214 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005215}
5216
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03005217static void l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
5218 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005219{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005220 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005221
Ido Yarivc2287682012-04-20 15:46:07 -03005222 chan = l2cap_global_chan_by_scid(0, cid, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005223 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005224 goto drop;
5225
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005226 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005227
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005228 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005229 goto drop;
5230
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005231 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005232 goto drop;
5233
Gustavo Padovan80b98022012-05-27 22:27:51 -03005234 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03005235 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005236
5237drop:
5238 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005239}
5240
Linus Torvalds1da177e2005-04-16 15:20:36 -07005241static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
5242{
5243 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07005244 u16 cid, len;
5245 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005246
5247 skb_pull(skb, L2CAP_HDR_SIZE);
5248 cid = __le16_to_cpu(lh->cid);
5249 len = __le16_to_cpu(lh->len);
5250
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005251 if (len != skb->len) {
5252 kfree_skb(skb);
5253 return;
5254 }
5255
Linus Torvalds1da177e2005-04-16 15:20:36 -07005256 BT_DBG("len %d, cid 0x%4.4x", len, cid);
5257
5258 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005259 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005260 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005261 l2cap_sig_channel(conn, skb);
5262 break;
5263
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005264 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02005265 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03005266 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005267 l2cap_conless_channel(conn, psm, skb);
5268 break;
5269
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005270 case L2CAP_CID_LE_DATA:
5271 l2cap_att_channel(conn, cid, skb);
5272 break;
5273
Anderson Brigliab501d6a2011-06-07 18:46:31 -03005274 case L2CAP_CID_SMP:
5275 if (smp_sig_channel(conn, skb))
5276 l2cap_conn_del(conn->hcon, EACCES);
5277 break;
5278
Linus Torvalds1da177e2005-04-16 15:20:36 -07005279 default:
5280 l2cap_data_channel(conn, cid, skb);
5281 break;
5282 }
5283}
5284
5285/* ---- L2CAP interface with lower layer (HCI) ---- */
5286
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005287int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005288{
5289 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005290 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005291
Linus Torvalds1da177e2005-04-16 15:20:36 -07005292 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
5293
5294 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005295 read_lock(&chan_list_lock);
5296 list_for_each_entry(c, &chan_list, global_l) {
5297 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005298
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005299 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005300 continue;
5301
5302 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005303 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005304 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005305 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005306 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005307 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
5308 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005309 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005310 lm2 |= HCI_LM_MASTER;
5311 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005312 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005313 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005314
5315 return exact ? lm1 : lm2;
5316}
5317
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005318int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005319{
Marcel Holtmann01394182006-07-03 10:02:46 +02005320 struct l2cap_conn *conn;
5321
Linus Torvalds1da177e2005-04-16 15:20:36 -07005322 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
5323
Linus Torvalds1da177e2005-04-16 15:20:36 -07005324 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005325 conn = l2cap_conn_add(hcon, status);
5326 if (conn)
5327 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02005328 } else
Joe Perchese1750722011-06-29 18:18:29 -07005329 l2cap_conn_del(hcon, bt_to_errno(status));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005330
5331 return 0;
5332}
5333
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005334int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01005335{
5336 struct l2cap_conn *conn = hcon->l2cap_data;
5337
5338 BT_DBG("hcon %p", hcon);
5339
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005340 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02005341 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01005342 return conn->disc_reason;
5343}
5344
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005345int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005346{
5347 BT_DBG("hcon %p reason %d", hcon, reason);
5348
Joe Perchese1750722011-06-29 18:18:29 -07005349 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005350 return 0;
5351}
5352
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005353static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005354{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03005355 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01005356 return;
5357
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005358 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005359 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005360 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005361 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03005362 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005363 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005364 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03005365 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005366 }
5367}
5368
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005369int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005370{
Marcel Holtmann40be4922008-07-14 20:13:50 +02005371 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005372 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005373
Marcel Holtmann01394182006-07-03 10:02:46 +02005374 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005375 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02005376
Linus Torvalds1da177e2005-04-16 15:20:36 -07005377 BT_DBG("conn %p", conn);
5378
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005379 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05305380 if (!status && encrypt)
5381 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02005382 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005383 }
5384
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005385 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005386
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005387 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005388 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005389
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005390 BT_DBG("chan->scid %d", chan->scid);
5391
5392 if (chan->scid == L2CAP_CID_LE_DATA) {
5393 if (!status && encrypt) {
5394 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02005395 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005396 }
5397
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005398 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005399 continue;
5400 }
5401
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03005402 if (test_bit(CONF_CONNECT_PEND, &chan->conf_state)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005403 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01005404 continue;
5405 }
5406
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005407 if (!status && (chan->state == BT_CONNECTED ||
5408 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03005409 struct sock *sk = chan->sk;
5410
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005411 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03005412 sk->sk_state_change(sk);
5413
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005414 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005415 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02005416 continue;
5417 }
5418
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005419 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005420 if (!status) {
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02005421 l2cap_send_conn_req(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005422 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005423 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005424 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005425 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005426 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005427 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005428 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005429
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005430 lock_sock(sk);
5431
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005432 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005433 if (test_bit(BT_SK_DEFER_SETUP,
5434 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005435 struct sock *parent = bt_sk(sk)->parent;
5436 res = L2CAP_CR_PEND;
5437 stat = L2CAP_CS_AUTHOR_PEND;
Ilia Kolomisnky05e9a2f2011-07-15 18:30:21 +00005438 if (parent)
5439 parent->sk_data_ready(parent, 0);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005440 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005441 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005442 res = L2CAP_CR_SUCCESS;
5443 stat = L2CAP_CS_NO_INFO;
5444 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005445 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005446 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005447 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005448 res = L2CAP_CR_SEC_BLOCK;
5449 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005450 }
5451
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005452 release_sock(sk);
5453
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03005454 rsp.scid = cpu_to_le16(chan->dcid);
5455 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005456 rsp.result = cpu_to_le16(res);
5457 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03005458 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
5459 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07005460
5461 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
5462 res == L2CAP_CR_SUCCESS) {
5463 char buf[128];
5464 set_bit(CONF_REQ_SENT, &chan->conf_state);
5465 l2cap_send_cmd(conn, l2cap_get_ident(conn),
5466 L2CAP_CONF_REQ,
5467 l2cap_build_conf_req(chan, buf),
5468 buf);
5469 chan->num_conf_req++;
5470 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005471 }
5472
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005473 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005474 }
5475
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005476 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005477
Linus Torvalds1da177e2005-04-16 15:20:36 -07005478 return 0;
5479}
5480
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005481int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005482{
5483 struct l2cap_conn *conn = hcon->l2cap_data;
5484
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02005485 if (!conn)
5486 conn = l2cap_conn_add(hcon, 0);
5487
5488 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005489 goto drop;
5490
5491 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
5492
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +02005493 if (!(flags & ACL_CONT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005494 struct l2cap_hdr *hdr;
5495 int len;
5496
5497 if (conn->rx_len) {
5498 BT_ERR("Unexpected start frame (len %d)", skb->len);
5499 kfree_skb(conn->rx_skb);
5500 conn->rx_skb = NULL;
5501 conn->rx_len = 0;
5502 l2cap_conn_unreliable(conn, ECOMM);
5503 }
5504
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03005505 /* Start fragment always begin with Basic L2CAP header */
5506 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005507 BT_ERR("Frame is too short (len %d)", skb->len);
5508 l2cap_conn_unreliable(conn, ECOMM);
5509 goto drop;
5510 }
5511
5512 hdr = (struct l2cap_hdr *) skb->data;
5513 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
5514
5515 if (len == skb->len) {
5516 /* Complete frame received */
5517 l2cap_recv_frame(conn, skb);
5518 return 0;
5519 }
5520
5521 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
5522
5523 if (skb->len > len) {
5524 BT_ERR("Frame is too long (len %d, expected len %d)",
5525 skb->len, len);
5526 l2cap_conn_unreliable(conn, ECOMM);
5527 goto drop;
5528 }
5529
5530 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03005531 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
5532 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005533 goto drop;
5534
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005535 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01005536 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005537 conn->rx_len = len - skb->len;
5538 } else {
5539 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
5540
5541 if (!conn->rx_len) {
5542 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
5543 l2cap_conn_unreliable(conn, ECOMM);
5544 goto drop;
5545 }
5546
5547 if (skb->len > conn->rx_len) {
5548 BT_ERR("Fragment is too long (len %d, expected %d)",
5549 skb->len, conn->rx_len);
5550 kfree_skb(conn->rx_skb);
5551 conn->rx_skb = NULL;
5552 conn->rx_len = 0;
5553 l2cap_conn_unreliable(conn, ECOMM);
5554 goto drop;
5555 }
5556
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005557 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01005558 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005559 conn->rx_len -= skb->len;
5560
5561 if (!conn->rx_len) {
5562 /* Complete frame received */
5563 l2cap_recv_frame(conn, conn->rx_skb);
5564 conn->rx_skb = NULL;
5565 }
5566 }
5567
5568drop:
5569 kfree_skb(skb);
5570 return 0;
5571}
5572
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005573static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005574{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005575 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005576
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005577 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005578
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005579 list_for_each_entry(c, &chan_list, global_l) {
5580 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005581
Gustavo F. Padovan903d3432011-02-10 14:16:06 -02005582 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 +01005583 batostr(&bt_sk(sk)->src),
5584 batostr(&bt_sk(sk)->dst),
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005585 c->state, __le16_to_cpu(c->psm),
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005586 c->scid, c->dcid, c->imtu, c->omtu,
5587 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02005588 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005589
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005590 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005591
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005592 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005593}
5594
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005595static int l2cap_debugfs_open(struct inode *inode, struct file *file)
5596{
5597 return single_open(file, l2cap_debugfs_show, inode->i_private);
5598}
5599
5600static const struct file_operations l2cap_debugfs_fops = {
5601 .open = l2cap_debugfs_open,
5602 .read = seq_read,
5603 .llseek = seq_lseek,
5604 .release = single_release,
5605};
5606
5607static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005608
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005609int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005610{
5611 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005612
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005613 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005614 if (err < 0)
5615 return err;
5616
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005617 if (bt_debugfs) {
5618 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
5619 bt_debugfs, NULL, &l2cap_debugfs_fops);
5620 if (!l2cap_debugfs)
5621 BT_ERR("Failed to create L2CAP debug file");
5622 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005623
Linus Torvalds1da177e2005-04-16 15:20:36 -07005624 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005625}
5626
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005627void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005628{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005629 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005630 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005631}
5632
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03005633module_param(disable_ertm, bool, 0644);
5634MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");