blob: e0abaf3cb6a59976c8a5b814d9ae088211ffe741 [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. Padovan710f9b0a2011-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
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530419static void l2cap_chan_destroy(struct l2cap_chan *chan)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300420{
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530421 BT_DBG("chan %p", chan);
422
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200423 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300424 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200425 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300426
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530427 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300428}
429
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530430void l2cap_chan_hold(struct l2cap_chan *c)
431{
432 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->refcnt));
433
434 atomic_inc(&c->refcnt);
435}
436
437void l2cap_chan_put(struct l2cap_chan *c)
438{
439 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->refcnt));
440
441 if (atomic_dec_and_test(&c->refcnt))
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530442 l2cap_chan_destroy(c);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530443}
444
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300445void l2cap_chan_set_defaults(struct l2cap_chan *chan)
446{
447 chan->fcs = L2CAP_FCS_CRC16;
448 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
449 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
450 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700451 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300452 chan->sec_level = BT_SECURITY_LOW;
453
454 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
455}
456
Andrei Emeltchenko14a28492012-03-23 16:31:49 +0200457static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200458{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300459 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200460 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200461
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200462 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100463
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300464 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200465
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200466 switch (chan->chan_type) {
467 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300468 if (conn->hcon->type == LE_LINK) {
469 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300470 chan->omtu = L2CAP_DEFAULT_MTU;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300471 chan->scid = L2CAP_CID_LE_DATA;
472 chan->dcid = L2CAP_CID_LE_DATA;
Ville Tervob62f3282011-02-10 22:38:50 -0300473 } else {
474 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300475 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300476 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300477 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200478 break;
479
480 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200481 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300482 chan->scid = L2CAP_CID_CONN_LESS;
483 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300484 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200485 break;
486
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300487 case L2CAP_CHAN_CONN_FIX_A2MP:
488 chan->scid = L2CAP_CID_A2MP;
489 chan->dcid = L2CAP_CID_A2MP;
490 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
491 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
492 break;
493
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200494 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200495 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300496 chan->scid = L2CAP_CID_SIGNALING;
497 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300498 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200499 }
500
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300501 chan->local_id = L2CAP_BESTEFFORT_ID;
502 chan->local_stype = L2CAP_SERV_BESTEFFORT;
503 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
504 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
505 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
506 chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO;
507
Ulisses Furquim371fd832011-12-21 20:02:36 -0200508 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300509
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200510 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200511}
512
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300513void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200514{
515 mutex_lock(&conn->chan_lock);
516 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200517 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200518}
519
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300520void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200521{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300522 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200523
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300524 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200525
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300526 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200527
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900528 if (conn) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300529 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200530 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200531
Ulisses Furquim371fd832011-12-21 20:02:36 -0200532 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300533
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300534 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300535
536 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
537 hci_conn_put(conn->hcon);
Marcel Holtmann01394182006-07-03 10:02:46 +0200538 }
539
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300540 if (chan->ops->teardown)
541 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200542
Mat Martineau28270112012-05-17 21:14:09 -0700543 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300544 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300545
Gustavo Padovanee556f62012-05-18 20:22:38 -0300546 switch(chan->mode) {
547 case L2CAP_MODE_BASIC:
548 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300549
Gustavo Padovanee556f62012-05-18 20:22:38 -0300550 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300551 __clear_retrans_timer(chan);
552 __clear_monitor_timer(chan);
553 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300554
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300555 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300556
Mat Martineau3c588192012-04-11 10:48:42 -0700557 l2cap_seq_list_free(&chan->srej_list);
558 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300559
560 /* fall through */
561
562 case L2CAP_MODE_STREAMING:
563 skb_queue_purge(&chan->tx_q);
564 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300565 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300566
567 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200568}
569
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300570void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300571{
572 struct l2cap_conn *conn = chan->conn;
573 struct sock *sk = chan->sk;
574
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200575 BT_DBG("chan %p state %s sk %p", chan,
576 state_to_string(chan->state), sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300577
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300578 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300579 case BT_LISTEN:
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300580 if (chan->ops->teardown)
581 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300582 break;
583
584 case BT_CONNECTED:
585 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300586 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300587 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300588 __set_chan_timer(chan, sk->sk_sndtimeo);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300589 l2cap_send_disconn_req(conn, chan, reason);
590 } else
591 l2cap_chan_del(chan, reason);
592 break;
593
594 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300595 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300596 conn->hcon->type == ACL_LINK) {
597 struct l2cap_conn_rsp rsp;
598 __u16 result;
599
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300600 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300601 result = L2CAP_CR_SEC_BLOCK;
602 else
603 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300604 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300605
606 rsp.scid = cpu_to_le16(chan->dcid);
607 rsp.dcid = cpu_to_le16(chan->scid);
608 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300609 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300610 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
611 sizeof(rsp), &rsp);
612 }
613
614 l2cap_chan_del(chan, reason);
615 break;
616
617 case BT_CONNECT:
618 case BT_DISCONN:
619 l2cap_chan_del(chan, reason);
620 break;
621
622 default:
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300623 if (chan->ops->teardown)
624 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300625 break;
626 }
627}
628
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300629static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530630{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300631 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300632 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530633 case BT_SECURITY_HIGH:
634 return HCI_AT_DEDICATED_BONDING_MITM;
635 case BT_SECURITY_MEDIUM:
636 return HCI_AT_DEDICATED_BONDING;
637 default:
638 return HCI_AT_NO_BONDING;
639 }
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +0300640 } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300641 if (chan->sec_level == BT_SECURITY_LOW)
642 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530643
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300644 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530645 return HCI_AT_NO_BONDING_MITM;
646 else
647 return HCI_AT_NO_BONDING;
648 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300649 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530650 case BT_SECURITY_HIGH:
651 return HCI_AT_GENERAL_BONDING_MITM;
652 case BT_SECURITY_MEDIUM:
653 return HCI_AT_GENERAL_BONDING;
654 default:
655 return HCI_AT_NO_BONDING;
656 }
657 }
658}
659
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200660/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200661int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200662{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300663 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100664 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200665
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300666 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100667
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300668 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200669}
670
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200671static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200672{
673 u8 id;
674
675 /* Get next available identificator.
676 * 1 - 128 are used by kernel.
677 * 129 - 199 are reserved.
678 * 200 - 254 are used by utilities like l2ping, etc.
679 */
680
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200681 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200682
683 if (++conn->tx_ident > 128)
684 conn->tx_ident = 1;
685
686 id = conn->tx_ident;
687
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200688 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200689
690 return id;
691}
692
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300693static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200694{
695 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200696 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200697
698 BT_DBG("code 0x%2.2x", code);
699
700 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300701 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200702
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200703 if (lmp_no_flush_capable(conn->hcon->hdev))
704 flags = ACL_START_NO_FLUSH;
705 else
706 flags = ACL_START;
707
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700708 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200709 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700710
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200711 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200712}
713
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200714static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
715{
716 struct hci_conn *hcon = chan->conn->hcon;
717 u16 flags;
718
719 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
720 skb->priority);
721
722 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
723 lmp_no_flush_capable(hcon->hdev))
724 flags = ACL_START_NO_FLUSH;
725 else
726 flags = ACL_START;
727
728 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
729 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730}
731
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700732static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
733{
734 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
735 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
736
737 if (enh & L2CAP_CTRL_FRAME_TYPE) {
738 /* S-Frame */
739 control->sframe = 1;
740 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
741 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
742
743 control->sar = 0;
744 control->txseq = 0;
745 } else {
746 /* I-Frame */
747 control->sframe = 0;
748 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
749 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
750
751 control->poll = 0;
752 control->super = 0;
753 }
754}
755
756static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
757{
758 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
759 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
760
761 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
762 /* S-Frame */
763 control->sframe = 1;
764 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
765 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
766
767 control->sar = 0;
768 control->txseq = 0;
769 } else {
770 /* I-Frame */
771 control->sframe = 0;
772 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
773 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
774
775 control->poll = 0;
776 control->super = 0;
777 }
778}
779
780static inline void __unpack_control(struct l2cap_chan *chan,
781 struct sk_buff *skb)
782{
783 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
784 __unpack_extended_control(get_unaligned_le32(skb->data),
785 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700786 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700787 } else {
788 __unpack_enhanced_control(get_unaligned_le16(skb->data),
789 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700790 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700791 }
792}
793
794static u32 __pack_extended_control(struct l2cap_ctrl *control)
795{
796 u32 packed;
797
798 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
799 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
800
801 if (control->sframe) {
802 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
803 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
804 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
805 } else {
806 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
807 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
808 }
809
810 return packed;
811}
812
813static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
814{
815 u16 packed;
816
817 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
818 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
819
820 if (control->sframe) {
821 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
822 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
823 packed |= L2CAP_CTRL_FRAME_TYPE;
824 } else {
825 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
826 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
827 }
828
829 return packed;
830}
831
832static inline void __pack_control(struct l2cap_chan *chan,
833 struct l2cap_ctrl *control,
834 struct sk_buff *skb)
835{
836 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
837 put_unaligned_le32(__pack_extended_control(control),
838 skb->data + L2CAP_HDR_SIZE);
839 } else {
840 put_unaligned_le16(__pack_enhanced_control(control),
841 skb->data + L2CAP_HDR_SIZE);
842 }
843}
844
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300845static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
846{
847 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
848 return L2CAP_EXT_HDR_SIZE;
849 else
850 return L2CAP_ENH_HDR_SIZE;
851}
852
Mat Martineaua67d7f62012-05-17 20:53:35 -0700853static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
854 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300855{
856 struct sk_buff *skb;
857 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300858 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300859
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300860 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300861 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300862
Mat Martineaua67d7f62012-05-17 20:53:35 -0700863 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300864
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300865 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700866 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300867
868 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300869 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300870 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300871
Mat Martineaua67d7f62012-05-17 20:53:35 -0700872 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
873 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
874 else
875 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300876
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300877 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700878 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300879 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300880 }
881
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200882 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700883 return skb;
884}
885
886static void l2cap_send_sframe(struct l2cap_chan *chan,
887 struct l2cap_ctrl *control)
888{
889 struct sk_buff *skb;
890 u32 control_field;
891
892 BT_DBG("chan %p, control %p", chan, control);
893
894 if (!control->sframe)
895 return;
896
897 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
898 !control->poll)
899 control->final = 1;
900
901 if (control->super == L2CAP_SUPER_RR)
902 clear_bit(CONN_RNR_SENT, &chan->conn_state);
903 else if (control->super == L2CAP_SUPER_RNR)
904 set_bit(CONN_RNR_SENT, &chan->conn_state);
905
906 if (control->super != L2CAP_SUPER_SREJ) {
907 chan->last_acked_seq = control->reqseq;
908 __clear_ack_timer(chan);
909 }
910
911 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
912 control->final, control->poll, control->super);
913
914 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
915 control_field = __pack_extended_control(control);
916 else
917 control_field = __pack_enhanced_control(control);
918
919 skb = l2cap_create_sframe_pdu(chan, control_field);
920 if (!IS_ERR(skb))
921 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300922}
923
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700924static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300925{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700926 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300927
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700928 BT_DBG("chan %p, poll %d", chan, poll);
929
930 memset(&control, 0, sizeof(control));
931 control.sframe = 1;
932 control.poll = poll;
933
934 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
935 control.super = L2CAP_SUPER_RNR;
936 else
937 control.super = L2CAP_SUPER_RR;
938
939 control.reqseq = chan->buffer_seq;
940 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300941}
942
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300943static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300944{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -0300945 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300946}
947
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +0200948static void l2cap_send_conn_req(struct l2cap_chan *chan)
949{
950 struct l2cap_conn *conn = chan->conn;
951 struct l2cap_conn_req req;
952
953 req.scid = cpu_to_le16(chan->scid);
954 req.psm = chan->psm;
955
956 chan->ident = l2cap_get_ident(conn);
957
958 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
959
960 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
961}
962
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300963static void l2cap_chan_ready(struct l2cap_chan *chan)
964{
Mat Martineau28270112012-05-17 21:14:09 -0700965 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300966 chan->conf_state = 0;
967 __clear_chan_timer(chan);
968
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -0300969 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300970
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +0300971 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300972}
973
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -0300974static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200975{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300976 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200977
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300978 if (conn->hcon->type == LE_LINK) {
979 l2cap_chan_ready(chan);
980 return;
981 }
982
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200983 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100984 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
985 return;
986
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200987 if (l2cap_chan_check_security(chan) &&
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +0200988 __l2cap_no_conn_pending(chan))
989 l2cap_send_conn_req(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200990 } else {
991 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300992 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200993
994 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
995 conn->info_ident = l2cap_get_ident(conn);
996
Marcel Holtmannba13ccd2012-03-01 14:25:33 -0800997 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200998
999 l2cap_send_cmd(conn, conn->info_ident,
1000 L2CAP_INFO_REQ, sizeof(req), &req);
1001 }
1002}
1003
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001004static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1005{
1006 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001007 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001008 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1009
1010 switch (mode) {
1011 case L2CAP_MODE_ERTM:
1012 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1013 case L2CAP_MODE_STREAMING:
1014 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1015 default:
1016 return 0x00;
1017 }
1018}
1019
Gustavo F. Padovan4519de92011-04-28 17:55:53 -03001020static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001021{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001022 struct sock *sk = chan->sk;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001023 struct l2cap_disconn_req req;
1024
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001025 if (!conn)
1026 return;
1027
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001028 if (chan->mode == L2CAP_MODE_ERTM) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001029 __clear_retrans_timer(chan);
1030 __clear_monitor_timer(chan);
1031 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001032 }
1033
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001034 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1035 __l2cap_state_change(chan, BT_DISCONN);
1036 return;
1037 }
1038
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001039 req.dcid = cpu_to_le16(chan->dcid);
1040 req.scid = cpu_to_le16(chan->scid);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001041 l2cap_send_cmd(conn, l2cap_get_ident(conn),
1042 L2CAP_DISCONN_REQ, sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001043
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001044 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001045 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001046 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001047 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001048}
1049
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001051static void l2cap_conn_start(struct l2cap_conn *conn)
1052{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001053 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001054
1055 BT_DBG("conn %p", conn);
1056
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001057 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001058
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001059 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001060 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001061
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001062 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001063
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001064 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001065 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001066 continue;
1067 }
1068
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001069 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001070 if (!l2cap_chan_check_security(chan) ||
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001071 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001072 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001073 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001074 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001075
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001076 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
1077 && test_bit(CONF_STATE2_DEVICE,
1078 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001079 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001080 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001081 continue;
1082 }
1083
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001084 l2cap_send_conn_req(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001085
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001086 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001087 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001088 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001089 rsp.scid = cpu_to_le16(chan->dcid);
1090 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001091
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001092 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001093 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001094 if (test_bit(BT_SK_DEFER_SETUP,
1095 &bt_sk(sk)->flags)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001096 struct sock *parent = bt_sk(sk)->parent;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001097 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1098 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Ilia Kolomisnky05e9a2f2011-07-15 18:30:21 +00001099 if (parent)
1100 parent->sk_data_ready(parent, 0);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001101
1102 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001103 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001104 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1105 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001106 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001107 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001108 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001109 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1110 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001111 }
1112
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001113 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
1114 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001115
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001116 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001117 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001118 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001119 continue;
1120 }
1121
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001122 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001123 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001124 l2cap_build_conf_req(chan, buf), buf);
1125 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001126 }
1127
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001128 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001129 }
1130
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001131 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001132}
1133
Ido Yarivc2287682012-04-20 15:46:07 -03001134/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001135 * Returns closest match, locked.
1136 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001137static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001138 bdaddr_t *src,
1139 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001140{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001141 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001142
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001143 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001144
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001145 list_for_each_entry(c, &chan_list, global_l) {
1146 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001147
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001148 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001149 continue;
1150
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001151 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001152 int src_match, dst_match;
1153 int src_any, dst_any;
1154
Ville Tervob62f3282011-02-10 22:38:50 -03001155 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001156 src_match = !bacmp(&bt_sk(sk)->src, src);
1157 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1158 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001159 read_unlock(&chan_list_lock);
1160 return c;
1161 }
Ville Tervob62f3282011-02-10 22:38:50 -03001162
1163 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001164 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1165 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1166 if ((src_match && dst_any) || (src_any && dst_match) ||
1167 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001168 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001169 }
1170 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001171
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001172 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001173
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001174 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001175}
1176
1177static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1178{
Gustavo F. Padovanc916fbe2011-04-04 16:00:55 -03001179 struct sock *parent, *sk;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001180 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001181
1182 BT_DBG("");
1183
1184 /* Check if we have socket listening on cid */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001185 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
Ido Yarivc2287682012-04-20 15:46:07 -03001186 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001187 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001188 return;
1189
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001190 parent = pchan->sk;
1191
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001192 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001193
Gustavo Padovan80b98022012-05-27 22:27:51 -03001194 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001195 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001196 goto clean;
1197
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001198 sk = chan->sk;
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001199
Ville Tervob62f3282011-02-10 22:38:50 -03001200 hci_conn_hold(conn->hcon);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001201 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
Ville Tervob62f3282011-02-10 22:38:50 -03001202
Ville Tervob62f3282011-02-10 22:38:50 -03001203 bacpy(&bt_sk(sk)->src, conn->src);
1204 bacpy(&bt_sk(sk)->dst, conn->dst);
1205
Gustavo F. Padovand1010242011-03-25 00:39:48 -03001206 bt_accept_enqueue(parent, sk);
1207
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001208 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001209
Gustavo Padovan6754e0d2012-05-25 09:30:56 -03001210 l2cap_chan_ready(chan);
Ville Tervob62f3282011-02-10 22:38:50 -03001211
Ville Tervob62f3282011-02-10 22:38:50 -03001212clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001213 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001214}
1215
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001216static void l2cap_conn_ready(struct l2cap_conn *conn)
1217{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001218 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001219 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001220
1221 BT_DBG("conn %p", conn);
1222
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001223 if (!hcon->out && hcon->type == LE_LINK)
Ville Tervob62f3282011-02-10 22:38:50 -03001224 l2cap_le_conn_ready(conn);
1225
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001226 if (hcon->out && hcon->type == LE_LINK)
1227 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001228
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001229 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001230
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001231 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001232
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001233 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001234
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001235 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1236 l2cap_chan_unlock(chan);
1237 continue;
1238 }
1239
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001240 if (hcon->type == LE_LINK) {
1241 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001242 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001243
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001244 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001245 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001246 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001247 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001248 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001249 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001250 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001251
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001252 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001253 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001254
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001255 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001256 }
1257
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001258 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001259}
1260
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001261/* Notify sockets that we cannot guaranty reliability anymore */
1262static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1263{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001264 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001265
1266 BT_DBG("conn %p", conn);
1267
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001268 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001269
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001270 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001271 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001272 __l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001273 }
1274
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001275 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001276}
1277
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001278static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001279{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001280 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001281 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001282
Marcel Holtmann984947d2009-02-06 23:35:19 +01001283 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001284 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001285
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001286 l2cap_conn_start(conn);
1287}
1288
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001289static void l2cap_conn_del(struct hci_conn *hcon, int err)
1290{
1291 struct l2cap_conn *conn = hcon->l2cap_data;
1292 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001293
1294 if (!conn)
1295 return;
1296
1297 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1298
1299 kfree_skb(conn->rx_skb);
1300
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001301 mutex_lock(&conn->chan_lock);
1302
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001303 /* Kill channels */
1304 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001305 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001306 l2cap_chan_lock(chan);
1307
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001308 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001309
1310 l2cap_chan_unlock(chan);
1311
Gustavo Padovan80b98022012-05-27 22:27:51 -03001312 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001313 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001314 }
1315
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001316 mutex_unlock(&conn->chan_lock);
1317
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001318 hci_chan_del(conn->hchan);
1319
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001320 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001321 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001322
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001323 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001324 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001325 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001326 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001327
1328 hcon->l2cap_data = NULL;
1329 kfree(conn);
1330}
1331
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001332static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001333{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001334 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
1335 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001336
Johan Hedbergd06cc412012-06-06 18:44:11 +08001337 BT_DBG("conn %p", conn);
1338
1339 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1340 smp_chan_destroy(conn);
1341 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1342 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001343}
1344
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
1346{
Marcel Holtmann01394182006-07-03 10:02:46 +02001347 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001348 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349
Marcel Holtmann01394182006-07-03 10:02:46 +02001350 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351 return conn;
1352
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001353 hchan = hci_chan_create(hcon);
1354 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001357 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
1358 if (!conn) {
1359 hci_chan_del(hchan);
1360 return NULL;
1361 }
1362
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363 hcon->l2cap_data = conn;
1364 conn->hcon = hcon;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001365 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001367 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001368
Ville Tervoacd7d372011-02-10 22:38:49 -03001369 if (hcon->hdev->le_mtu && hcon->type == LE_LINK)
1370 conn->mtu = hcon->hdev->le_mtu;
1371 else
1372 conn->mtu = hcon->hdev->acl_mtu;
1373
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374 conn->src = &hcon->hdev->bdaddr;
1375 conn->dst = &hcon->dst;
1376
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001377 conn->feat_mask = 0;
1378
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001380 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001381
1382 INIT_LIST_HEAD(&conn->chan_l);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001384 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001385 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001386 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001387 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001388
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001389 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001390
Linus Torvalds1da177e2005-04-16 15:20:36 -07001391 return conn;
1392}
1393
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001395
Ido Yarivc2287682012-04-20 15:46:07 -03001396/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397 * Returns closest match.
1398 */
Ido Yarivc2287682012-04-20 15:46:07 -03001399static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1400 bdaddr_t *src,
1401 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001403 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001405 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001406
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001407 list_for_each_entry(c, &chan_list, global_l) {
1408 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001409
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001410 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411 continue;
1412
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001413 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001414 int src_match, dst_match;
1415 int src_any, dst_any;
1416
Linus Torvalds1da177e2005-04-16 15:20:36 -07001417 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001418 src_match = !bacmp(&bt_sk(sk)->src, src);
1419 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1420 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001421 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001422 return c;
1423 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424
1425 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001426 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1427 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1428 if ((src_match && dst_any) || (src_any && dst_match) ||
1429 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001430 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431 }
1432 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001433
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001434 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001435
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001436 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437}
1438
Andre Guedes8e9f9892012-04-24 21:02:55 -03001439int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1440 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001442 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444 struct l2cap_conn *conn;
1445 struct hci_conn *hcon;
1446 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001447 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001448 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001449
Andre Guedes8e9f9892012-04-24 21:02:55 -03001450 BT_DBG("%s -> %s (type %u) psm 0x%2.2x", batostr(src), batostr(dst),
1451 dst_type, __le16_to_cpu(chan->psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001453 hdev = hci_get_route(dst, src);
1454 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455 return -EHOSTUNREACH;
1456
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001457 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001458
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001459 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001460
1461 /* PSM must be odd and lsb of upper byte must be 0 */
1462 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
1463 chan->chan_type != L2CAP_CHAN_RAW) {
1464 err = -EINVAL;
1465 goto done;
1466 }
1467
1468 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1469 err = -EINVAL;
1470 goto done;
1471 }
1472
1473 switch (chan->mode) {
1474 case L2CAP_MODE_BASIC:
1475 break;
1476 case L2CAP_MODE_ERTM:
1477 case L2CAP_MODE_STREAMING:
1478 if (!disable_ertm)
1479 break;
1480 /* fall through */
1481 default:
1482 err = -ENOTSUPP;
1483 goto done;
1484 }
1485
Gustavo Padovan0797e012012-05-27 22:27:54 -03001486 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001487 case BT_CONNECT:
1488 case BT_CONNECT2:
1489 case BT_CONFIG:
1490 /* Already connecting */
1491 err = 0;
1492 goto done;
1493
1494 case BT_CONNECTED:
1495 /* Already connected */
1496 err = -EISCONN;
1497 goto done;
1498
1499 case BT_OPEN:
1500 case BT_BOUND:
1501 /* Can connect */
1502 break;
1503
1504 default:
1505 err = -EBADFD;
1506 goto done;
1507 }
1508
1509 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001510 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001511 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001512 release_sock(sk);
1513
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001514 chan->psm = psm;
1515 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001517 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001518
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001519 if (chan->dcid == L2CAP_CID_LE_DATA)
Andre Guedes8e9f9892012-04-24 21:02:55 -03001520 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001521 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001522 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001523 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001524 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001525
Ville Tervo30e76272011-02-22 16:10:53 -03001526 if (IS_ERR(hcon)) {
1527 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001528 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001529 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530
1531 conn = l2cap_conn_add(hcon, 0);
1532 if (!conn) {
1533 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001534 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535 goto done;
1536 }
1537
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001538 if (hcon->type == LE_LINK) {
1539 err = 0;
1540
1541 if (!list_empty(&conn->chan_l)) {
1542 err = -EBUSY;
1543 hci_conn_put(hcon);
1544 }
1545
1546 if (err)
1547 goto done;
1548 }
1549
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550 /* Update source addr of the socket */
1551 bacpy(src, conn->src);
1552
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001553 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001554 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001555 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001556
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001557 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001558 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559
1560 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001561 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001562 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001563 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001564 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001565 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001566 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567 }
1568
Ville Tervo30e76272011-02-22 16:10:53 -03001569 err = 0;
1570
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001572 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001573 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 hci_dev_put(hdev);
1575 return err;
1576}
1577
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001578int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001579{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001580 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001581 DECLARE_WAITQUEUE(wait, current);
1582 int err = 0;
1583 int timeo = HZ/5;
1584
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001585 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001586 set_current_state(TASK_INTERRUPTIBLE);
1587 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001588 if (!timeo)
1589 timeo = HZ/5;
1590
1591 if (signal_pending(current)) {
1592 err = sock_intr_errno(timeo);
1593 break;
1594 }
1595
1596 release_sock(sk);
1597 timeo = schedule_timeout(timeo);
1598 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001599 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001600
1601 err = sock_error(sk);
1602 if (err)
1603 break;
1604 }
1605 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001606 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001607 return err;
1608}
1609
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001610static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001611{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001612 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001613 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001614
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001615 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001616
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001617 l2cap_chan_lock(chan);
1618
Mat Martineau80909e02012-05-17 20:53:50 -07001619 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001620 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001621 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001622 return;
1623 }
1624
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001625 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001626
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 F. Padovan721c4182011-06-23 19:29:58 -03001631static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001632{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001633 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001634 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001635
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001636 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001637
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001638 l2cap_chan_lock(chan);
1639
Mat Martineau80909e02012-05-17 20:53:50 -07001640 if (!chan->conn) {
1641 l2cap_chan_unlock(chan);
1642 l2cap_chan_put(chan);
1643 return;
1644 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001645
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001646 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001647 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001648 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001649}
1650
Gustavo Padovand6603662012-05-21 13:58:22 -03001651static void l2cap_streaming_send(struct l2cap_chan *chan,
1652 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001653{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001654 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001655 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001656
Mat Martineau37339372012-05-17 20:53:33 -07001657 BT_DBG("chan %p, skbs %p", chan, skbs);
1658
Mat Martineau37339372012-05-17 20:53:33 -07001659 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1660
1661 while (!skb_queue_empty(&chan->tx_q)) {
1662
1663 skb = skb_dequeue(&chan->tx_q);
1664
1665 bt_cb(skb)->control.retries = 1;
1666 control = &bt_cb(skb)->control;
1667
1668 control->reqseq = 0;
1669 control->txseq = chan->next_tx_seq;
1670
1671 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001672
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001673 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001674 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1675 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001676 }
1677
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001678 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001679
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001680 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001681
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001682 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001683 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001684 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001685}
1686
Szymon Janc67c9e842011-07-28 16:24:33 +02001687static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001688{
1689 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001690 struct l2cap_ctrl *control;
1691 int sent = 0;
1692
1693 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001694
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001695 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001696 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001697
Mat Martineau94122bb2012-05-02 09:42:02 -07001698 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1699 return 0;
1700
Mat Martineau18a48e72012-05-17 20:53:34 -07001701 while (chan->tx_send_head &&
1702 chan->unacked_frames < chan->remote_tx_win &&
1703 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001704
Mat Martineau18a48e72012-05-17 20:53:34 -07001705 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001706
Mat Martineau18a48e72012-05-17 20:53:34 -07001707 bt_cb(skb)->control.retries = 1;
1708 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001709
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001710 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001711 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001712
Mat Martineau18a48e72012-05-17 20:53:34 -07001713 control->reqseq = chan->buffer_seq;
1714 chan->last_acked_seq = chan->buffer_seq;
1715 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001716
Mat Martineau18a48e72012-05-17 20:53:34 -07001717 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001718
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001719 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001720 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1721 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001722 }
1723
Mat Martineau18a48e72012-05-17 20:53:34 -07001724 /* Clone after data has been modified. Data is assumed to be
1725 read-only (for locking purposes) on cloned sk_buffs.
1726 */
1727 tx_skb = skb_clone(skb, GFP_KERNEL);
1728
1729 if (!tx_skb)
1730 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001731
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001732 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001733
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001734 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07001735 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03001736 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07001737 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001738
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001739 if (skb_queue_is_last(&chan->tx_q, skb))
1740 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001741 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001742 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07001743
1744 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001745 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001746 }
1747
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001748 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
1749 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07001750
1751 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001752}
1753
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001754static void l2cap_ertm_resend(struct l2cap_chan *chan)
1755{
1756 struct l2cap_ctrl control;
1757 struct sk_buff *skb;
1758 struct sk_buff *tx_skb;
1759 u16 seq;
1760
1761 BT_DBG("chan %p", chan);
1762
1763 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1764 return;
1765
1766 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
1767 seq = l2cap_seq_list_pop(&chan->retrans_list);
1768
1769 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
1770 if (!skb) {
1771 BT_DBG("Error: Can't retransmit seq %d, frame missing",
1772 seq);
1773 continue;
1774 }
1775
1776 bt_cb(skb)->control.retries++;
1777 control = bt_cb(skb)->control;
1778
1779 if (chan->max_tx != 0 &&
1780 bt_cb(skb)->control.retries > chan->max_tx) {
1781 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
1782 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
1783 l2cap_seq_list_clear(&chan->retrans_list);
1784 break;
1785 }
1786
1787 control.reqseq = chan->buffer_seq;
1788 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
1789 control.final = 1;
1790 else
1791 control.final = 0;
1792
1793 if (skb_cloned(skb)) {
1794 /* Cloned sk_buffs are read-only, so we need a
1795 * writeable copy
1796 */
1797 tx_skb = skb_copy(skb, GFP_ATOMIC);
1798 } else {
1799 tx_skb = skb_clone(skb, GFP_ATOMIC);
1800 }
1801
1802 if (!tx_skb) {
1803 l2cap_seq_list_clear(&chan->retrans_list);
1804 break;
1805 }
1806
1807 /* Update skb contents */
1808 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
1809 put_unaligned_le32(__pack_extended_control(&control),
1810 tx_skb->data + L2CAP_HDR_SIZE);
1811 } else {
1812 put_unaligned_le16(__pack_enhanced_control(&control),
1813 tx_skb->data + L2CAP_HDR_SIZE);
1814 }
1815
1816 if (chan->fcs == L2CAP_FCS_CRC16) {
1817 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
1818 put_unaligned_le16(fcs, skb_put(tx_skb,
1819 L2CAP_FCS_SIZE));
1820 }
1821
1822 l2cap_do_send(chan, tx_skb);
1823
1824 BT_DBG("Resent txseq %d", control.txseq);
1825
1826 chan->last_acked_seq = chan->buffer_seq;
1827 }
1828}
1829
Mat Martineauf80842a2012-05-17 20:53:46 -07001830static void l2cap_retransmit(struct l2cap_chan *chan,
1831 struct l2cap_ctrl *control)
1832{
1833 BT_DBG("chan %p, control %p", chan, control);
1834
1835 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
1836 l2cap_ertm_resend(chan);
1837}
1838
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001839static void l2cap_retransmit_all(struct l2cap_chan *chan,
1840 struct l2cap_ctrl *control)
1841{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001842 struct sk_buff *skb;
1843
1844 BT_DBG("chan %p, control %p", chan, control);
1845
1846 if (control->poll)
1847 set_bit(CONN_SEND_FBIT, &chan->conn_state);
1848
1849 l2cap_seq_list_clear(&chan->retrans_list);
1850
1851 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1852 return;
1853
1854 if (chan->unacked_frames) {
1855 skb_queue_walk(&chan->tx_q, skb) {
1856 if (bt_cb(skb)->control.txseq == control->reqseq ||
1857 skb == chan->tx_send_head)
1858 break;
1859 }
1860
1861 skb_queue_walk_from(&chan->tx_q, skb) {
1862 if (skb == chan->tx_send_head)
1863 break;
1864
1865 l2cap_seq_list_append(&chan->retrans_list,
1866 bt_cb(skb)->control.txseq);
1867 }
1868
1869 l2cap_ertm_resend(chan);
1870 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001871}
1872
Szymon Jancb17e73b2012-01-11 10:59:47 +01001873static void l2cap_send_ack(struct l2cap_chan *chan)
1874{
Mat Martineau0a0aba42012-05-17 20:53:39 -07001875 struct l2cap_ctrl control;
1876 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
1877 chan->last_acked_seq);
1878 int threshold;
1879
1880 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
1881 chan, chan->last_acked_seq, chan->buffer_seq);
1882
1883 memset(&control, 0, sizeof(control));
1884 control.sframe = 1;
1885
1886 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
1887 chan->rx_state == L2CAP_RX_STATE_RECV) {
1888 __clear_ack_timer(chan);
1889 control.super = L2CAP_SUPER_RNR;
1890 control.reqseq = chan->buffer_seq;
1891 l2cap_send_sframe(chan, &control);
1892 } else {
1893 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
1894 l2cap_ertm_send(chan);
1895 /* If any i-frames were sent, they included an ack */
1896 if (chan->buffer_seq == chan->last_acked_seq)
1897 frames_to_ack = 0;
1898 }
1899
Mat Martineauc20f8e32012-07-10 05:47:07 -07001900 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07001901 * Calculate without mul or div
1902 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07001903 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07001904 threshold += threshold << 1;
1905 threshold >>= 2;
1906
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001907 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07001908 threshold);
1909
1910 if (frames_to_ack >= threshold) {
1911 __clear_ack_timer(chan);
1912 control.super = L2CAP_SUPER_RR;
1913 control.reqseq = chan->buffer_seq;
1914 l2cap_send_sframe(chan, &control);
1915 frames_to_ack = 0;
1916 }
1917
1918 if (frames_to_ack)
1919 __set_ack_timer(chan);
1920 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01001921}
1922
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001923static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
1924 struct msghdr *msg, int len,
1925 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02001927 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001928 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03001929 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001930
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001931 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001932 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933
1934 sent += count;
1935 len -= count;
1936
1937 /* Continuation fragments (no L2CAP header) */
1938 frag = &skb_shinfo(skb)->frag_list;
1939 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001940 struct sk_buff *tmp;
1941
Linus Torvalds1da177e2005-04-16 15:20:36 -07001942 count = min_t(unsigned int, conn->mtu, len);
1943
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001944 tmp = chan->ops->alloc_skb(chan, count,
1945 msg->msg_flags & MSG_DONTWAIT);
1946 if (IS_ERR(tmp))
1947 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001948
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001949 *frag = tmp;
1950
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001951 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1952 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001953
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001954 (*frag)->priority = skb->priority;
1955
Linus Torvalds1da177e2005-04-16 15:20:36 -07001956 sent += count;
1957 len -= count;
1958
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03001959 skb->len += (*frag)->len;
1960 skb->data_len += (*frag)->len;
1961
Linus Torvalds1da177e2005-04-16 15:20:36 -07001962 frag = &(*frag)->next;
1963 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001964
1965 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001966}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001967
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001968static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001969 struct msghdr *msg, size_t len,
1970 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001971{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001972 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001973 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03001974 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001975 struct l2cap_hdr *lh;
1976
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001977 BT_DBG("chan %p len %zu priority %u", chan, len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001978
1979 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001980
1981 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03001982 msg->msg_flags & MSG_DONTWAIT);
1983 if (IS_ERR(skb))
1984 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001985
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001986 skb->priority = priority;
1987
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001988 /* Create L2CAP header */
1989 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001990 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03001991 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
1992 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001993
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02001994 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001995 if (unlikely(err < 0)) {
1996 kfree_skb(skb);
1997 return ERR_PTR(err);
1998 }
1999 return skb;
2000}
2001
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002002static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002003 struct msghdr *msg, size_t len,
2004 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002005{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002006 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002007 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002008 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002009 struct l2cap_hdr *lh;
2010
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002011 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002012
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002013 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002014
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002015 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002016 msg->msg_flags & MSG_DONTWAIT);
2017 if (IS_ERR(skb))
2018 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002019
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002020 skb->priority = priority;
2021
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002022 /* Create L2CAP header */
2023 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002024 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002025 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002026
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002027 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002028 if (unlikely(err < 0)) {
2029 kfree_skb(skb);
2030 return ERR_PTR(err);
2031 }
2032 return skb;
2033}
2034
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002035static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002036 struct msghdr *msg, size_t len,
2037 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002038{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002039 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002040 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002041 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002042 struct l2cap_hdr *lh;
2043
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002044 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002045
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002046 if (!conn)
2047 return ERR_PTR(-ENOTCONN);
2048
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002049 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002050
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002051 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002052 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002053
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002054 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002055 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002056
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002057 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002058
2059 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002060 msg->msg_flags & MSG_DONTWAIT);
2061 if (IS_ERR(skb))
2062 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002063
2064 /* Create L2CAP header */
2065 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002066 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002067 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002068
Mat Martineau18a48e72012-05-17 20:53:34 -07002069 /* Control header is populated later */
2070 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2071 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2072 else
2073 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002074
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002075 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002076 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002077
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002078 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002079 if (unlikely(err < 0)) {
2080 kfree_skb(skb);
2081 return ERR_PTR(err);
2082 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002083
Mat Martineau18a48e72012-05-17 20:53:34 -07002084 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002085 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002086 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002087}
2088
Mat Martineau94122bb2012-05-02 09:42:02 -07002089static int l2cap_segment_sdu(struct l2cap_chan *chan,
2090 struct sk_buff_head *seg_queue,
2091 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002092{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002093 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002094 u16 sdu_len;
2095 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002096 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002097
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002098 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002099
Mat Martineau94122bb2012-05-02 09:42:02 -07002100 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2101 * so fragmented skbs are not used. The HCI layer's handling
2102 * of fragmented skbs is not compatible with ERTM's queueing.
2103 */
2104
2105 /* PDU size is derived from the HCI MTU */
2106 pdu_len = chan->conn->mtu;
2107
2108 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
2109
2110 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002111 if (chan->fcs)
2112 pdu_len -= L2CAP_FCS_SIZE;
2113
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002114 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002115
2116 /* Remote device may have requested smaller PDUs */
2117 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2118
2119 if (len <= pdu_len) {
2120 sar = L2CAP_SAR_UNSEGMENTED;
2121 sdu_len = 0;
2122 pdu_len = len;
2123 } else {
2124 sar = L2CAP_SAR_START;
2125 sdu_len = len;
2126 pdu_len -= L2CAP_SDULEN_SIZE;
2127 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002128
2129 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002130 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002131
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002132 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002133 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002134 return PTR_ERR(skb);
2135 }
2136
Mat Martineau94122bb2012-05-02 09:42:02 -07002137 bt_cb(skb)->control.sar = sar;
2138 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002139
Mat Martineau94122bb2012-05-02 09:42:02 -07002140 len -= pdu_len;
2141 if (sdu_len) {
2142 sdu_len = 0;
2143 pdu_len += L2CAP_SDULEN_SIZE;
2144 }
2145
2146 if (len <= pdu_len) {
2147 sar = L2CAP_SAR_END;
2148 pdu_len = len;
2149 } else {
2150 sar = L2CAP_SAR_CONTINUE;
2151 }
2152 }
2153
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002154 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002155}
2156
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002157int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
2158 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002159{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002160 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002161 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002162 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002163
2164 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002165 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002166 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002167 if (IS_ERR(skb))
2168 return PTR_ERR(skb);
2169
2170 l2cap_do_send(chan, skb);
2171 return len;
2172 }
2173
2174 switch (chan->mode) {
2175 case L2CAP_MODE_BASIC:
2176 /* Check outgoing MTU */
2177 if (len > chan->omtu)
2178 return -EMSGSIZE;
2179
2180 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002181 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002182 if (IS_ERR(skb))
2183 return PTR_ERR(skb);
2184
2185 l2cap_do_send(chan, skb);
2186 err = len;
2187 break;
2188
2189 case L2CAP_MODE_ERTM:
2190 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002191 /* Check outgoing MTU */
2192 if (len > chan->omtu) {
2193 err = -EMSGSIZE;
2194 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002195 }
2196
Mat Martineau94122bb2012-05-02 09:42:02 -07002197 __skb_queue_head_init(&seg_queue);
2198
2199 /* Do segmentation before calling in to the state machine,
2200 * since it's possible to block while waiting for memory
2201 * allocation.
2202 */
2203 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2204
2205 /* The channel could have been closed while segmenting,
2206 * check that it is still connected.
2207 */
2208 if (chan->state != BT_CONNECTED) {
2209 __skb_queue_purge(&seg_queue);
2210 err = -ENOTCONN;
2211 }
2212
2213 if (err)
2214 break;
2215
Mat Martineau37339372012-05-17 20:53:33 -07002216 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002217 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002218 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002219 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002220
Gustavo Padovand6603662012-05-21 13:58:22 -03002221 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002222
Mat Martineau94122bb2012-05-02 09:42:02 -07002223 /* If the skbs were not queued for sending, they'll still be in
2224 * seg_queue and need to be purged.
2225 */
2226 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002227 break;
2228
2229 default:
2230 BT_DBG("bad state %1.1x", chan->mode);
2231 err = -EBADFD;
2232 }
2233
2234 return err;
2235}
2236
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002237static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2238{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002239 struct l2cap_ctrl control;
2240 u16 seq;
2241
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002242 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002243
2244 memset(&control, 0, sizeof(control));
2245 control.sframe = 1;
2246 control.super = L2CAP_SUPER_SREJ;
2247
2248 for (seq = chan->expected_tx_seq; seq != txseq;
2249 seq = __next_seq(chan, seq)) {
2250 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2251 control.reqseq = seq;
2252 l2cap_send_sframe(chan, &control);
2253 l2cap_seq_list_append(&chan->srej_list, seq);
2254 }
2255 }
2256
2257 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002258}
2259
2260static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2261{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002262 struct l2cap_ctrl control;
2263
2264 BT_DBG("chan %p", chan);
2265
2266 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2267 return;
2268
2269 memset(&control, 0, sizeof(control));
2270 control.sframe = 1;
2271 control.super = L2CAP_SUPER_SREJ;
2272 control.reqseq = chan->srej_list.tail;
2273 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002274}
2275
2276static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2277{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002278 struct l2cap_ctrl control;
2279 u16 initial_head;
2280 u16 seq;
2281
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002282 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002283
2284 memset(&control, 0, sizeof(control));
2285 control.sframe = 1;
2286 control.super = L2CAP_SUPER_SREJ;
2287
2288 /* Capture initial list head to allow only one pass through the list. */
2289 initial_head = chan->srej_list.head;
2290
2291 do {
2292 seq = l2cap_seq_list_pop(&chan->srej_list);
2293 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2294 break;
2295
2296 control.reqseq = seq;
2297 l2cap_send_sframe(chan, &control);
2298 l2cap_seq_list_append(&chan->srej_list, seq);
2299 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002300}
2301
Mat Martineau608bcc62012-05-17 20:53:32 -07002302static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2303{
2304 struct sk_buff *acked_skb;
2305 u16 ackseq;
2306
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002307 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002308
2309 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2310 return;
2311
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002312 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002313 chan->expected_ack_seq, chan->unacked_frames);
2314
2315 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2316 ackseq = __next_seq(chan, ackseq)) {
2317
2318 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2319 if (acked_skb) {
2320 skb_unlink(acked_skb, &chan->tx_q);
2321 kfree_skb(acked_skb);
2322 chan->unacked_frames--;
2323 }
2324 }
2325
2326 chan->expected_ack_seq = reqseq;
2327
2328 if (chan->unacked_frames == 0)
2329 __clear_retrans_timer(chan);
2330
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002331 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002332}
2333
2334static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2335{
2336 BT_DBG("chan %p", chan);
2337
2338 chan->expected_tx_seq = chan->buffer_seq;
2339 l2cap_seq_list_clear(&chan->srej_list);
2340 skb_queue_purge(&chan->srej_q);
2341 chan->rx_state = L2CAP_RX_STATE_RECV;
2342}
2343
Gustavo Padovand6603662012-05-21 13:58:22 -03002344static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2345 struct l2cap_ctrl *control,
2346 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002347{
Mat Martineau608bcc62012-05-17 20:53:32 -07002348 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2349 event);
2350
2351 switch (event) {
2352 case L2CAP_EV_DATA_REQUEST:
2353 if (chan->tx_send_head == NULL)
2354 chan->tx_send_head = skb_peek(skbs);
2355
2356 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2357 l2cap_ertm_send(chan);
2358 break;
2359 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2360 BT_DBG("Enter LOCAL_BUSY");
2361 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2362
2363 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2364 /* The SREJ_SENT state must be aborted if we are to
2365 * enter the LOCAL_BUSY state.
2366 */
2367 l2cap_abort_rx_srej_sent(chan);
2368 }
2369
2370 l2cap_send_ack(chan);
2371
2372 break;
2373 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2374 BT_DBG("Exit LOCAL_BUSY");
2375 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2376
2377 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2378 struct l2cap_ctrl local_control;
2379
2380 memset(&local_control, 0, sizeof(local_control));
2381 local_control.sframe = 1;
2382 local_control.super = L2CAP_SUPER_RR;
2383 local_control.poll = 1;
2384 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002385 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002386
2387 chan->retry_count = 1;
2388 __set_monitor_timer(chan);
2389 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2390 }
2391 break;
2392 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2393 l2cap_process_reqseq(chan, control->reqseq);
2394 break;
2395 case L2CAP_EV_EXPLICIT_POLL:
2396 l2cap_send_rr_or_rnr(chan, 1);
2397 chan->retry_count = 1;
2398 __set_monitor_timer(chan);
2399 __clear_ack_timer(chan);
2400 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2401 break;
2402 case L2CAP_EV_RETRANS_TO:
2403 l2cap_send_rr_or_rnr(chan, 1);
2404 chan->retry_count = 1;
2405 __set_monitor_timer(chan);
2406 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2407 break;
2408 case L2CAP_EV_RECV_FBIT:
2409 /* Nothing to process */
2410 break;
2411 default:
2412 break;
2413 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002414}
2415
Gustavo Padovand6603662012-05-21 13:58:22 -03002416static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2417 struct l2cap_ctrl *control,
2418 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002419{
Mat Martineau608bcc62012-05-17 20:53:32 -07002420 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2421 event);
2422
2423 switch (event) {
2424 case L2CAP_EV_DATA_REQUEST:
2425 if (chan->tx_send_head == NULL)
2426 chan->tx_send_head = skb_peek(skbs);
2427 /* Queue data, but don't send. */
2428 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2429 break;
2430 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2431 BT_DBG("Enter LOCAL_BUSY");
2432 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2433
2434 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2435 /* The SREJ_SENT state must be aborted if we are to
2436 * enter the LOCAL_BUSY state.
2437 */
2438 l2cap_abort_rx_srej_sent(chan);
2439 }
2440
2441 l2cap_send_ack(chan);
2442
2443 break;
2444 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2445 BT_DBG("Exit LOCAL_BUSY");
2446 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2447
2448 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2449 struct l2cap_ctrl local_control;
2450 memset(&local_control, 0, sizeof(local_control));
2451 local_control.sframe = 1;
2452 local_control.super = L2CAP_SUPER_RR;
2453 local_control.poll = 1;
2454 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002455 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002456
2457 chan->retry_count = 1;
2458 __set_monitor_timer(chan);
2459 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2460 }
2461 break;
2462 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2463 l2cap_process_reqseq(chan, control->reqseq);
2464
2465 /* Fall through */
2466
2467 case L2CAP_EV_RECV_FBIT:
2468 if (control && control->final) {
2469 __clear_monitor_timer(chan);
2470 if (chan->unacked_frames > 0)
2471 __set_retrans_timer(chan);
2472 chan->retry_count = 0;
2473 chan->tx_state = L2CAP_TX_STATE_XMIT;
2474 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2475 }
2476 break;
2477 case L2CAP_EV_EXPLICIT_POLL:
2478 /* Ignore */
2479 break;
2480 case L2CAP_EV_MONITOR_TO:
2481 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2482 l2cap_send_rr_or_rnr(chan, 1);
2483 __set_monitor_timer(chan);
2484 chan->retry_count++;
2485 } else {
2486 l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
2487 }
2488 break;
2489 default:
2490 break;
2491 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002492}
2493
Gustavo Padovand6603662012-05-21 13:58:22 -03002494static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2495 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002496{
Mat Martineau608bcc62012-05-17 20:53:32 -07002497 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2498 chan, control, skbs, event, chan->tx_state);
2499
2500 switch (chan->tx_state) {
2501 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002502 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002503 break;
2504 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002505 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002506 break;
2507 default:
2508 /* Ignore event */
2509 break;
2510 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002511}
2512
Mat Martineau4b51dae92012-05-17 20:53:37 -07002513static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2514 struct l2cap_ctrl *control)
2515{
2516 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002517 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002518}
2519
Mat Martineauf80842a2012-05-17 20:53:46 -07002520static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2521 struct l2cap_ctrl *control)
2522{
2523 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002524 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002525}
2526
Linus Torvalds1da177e2005-04-16 15:20:36 -07002527/* Copy frame to all raw sockets on that connection */
2528static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2529{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002530 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002531 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002532
2533 BT_DBG("conn %p", conn);
2534
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002535 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002536
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002537 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002538 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002539 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002540 continue;
2541
2542 /* Don't send frame to the socket it came from */
2543 if (skb->sk == sk)
2544 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002545 nskb = skb_clone(skb, GFP_ATOMIC);
2546 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002547 continue;
2548
Gustavo Padovan80b98022012-05-27 22:27:51 -03002549 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002550 kfree_skb(nskb);
2551 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002552
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002553 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002554}
2555
2556/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002557static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2558 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002559{
2560 struct sk_buff *skb, **frag;
2561 struct l2cap_cmd_hdr *cmd;
2562 struct l2cap_hdr *lh;
2563 int len, count;
2564
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002565 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2566 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567
2568 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2569 count = min_t(unsigned int, conn->mtu, len);
2570
2571 skb = bt_skb_alloc(count, GFP_ATOMIC);
2572 if (!skb)
2573 return NULL;
2574
2575 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002576 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002577
2578 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002579 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002580 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002581 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002582
2583 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2584 cmd->code = code;
2585 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002586 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002587
2588 if (dlen) {
2589 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2590 memcpy(skb_put(skb, count), data, count);
2591 data += count;
2592 }
2593
2594 len -= skb->len;
2595
2596 /* Continuation fragments (no L2CAP header) */
2597 frag = &skb_shinfo(skb)->frag_list;
2598 while (len) {
2599 count = min_t(unsigned int, conn->mtu, len);
2600
2601 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2602 if (!*frag)
2603 goto fail;
2604
2605 memcpy(skb_put(*frag, count), data, count);
2606
2607 len -= count;
2608 data += count;
2609
2610 frag = &(*frag)->next;
2611 }
2612
2613 return skb;
2614
2615fail:
2616 kfree_skb(skb);
2617 return NULL;
2618}
2619
2620static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2621{
2622 struct l2cap_conf_opt *opt = *ptr;
2623 int len;
2624
2625 len = L2CAP_CONF_OPT_SIZE + opt->len;
2626 *ptr += len;
2627
2628 *type = opt->type;
2629 *olen = opt->len;
2630
2631 switch (opt->len) {
2632 case 1:
2633 *val = *((u8 *) opt->val);
2634 break;
2635
2636 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002637 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002638 break;
2639
2640 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002641 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002642 break;
2643
2644 default:
2645 *val = (unsigned long) opt->val;
2646 break;
2647 }
2648
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002649 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002650 return len;
2651}
2652
Linus Torvalds1da177e2005-04-16 15:20:36 -07002653static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2654{
2655 struct l2cap_conf_opt *opt = *ptr;
2656
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002657 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002658
2659 opt->type = type;
2660 opt->len = len;
2661
2662 switch (len) {
2663 case 1:
2664 *((u8 *) opt->val) = val;
2665 break;
2666
2667 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002668 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002669 break;
2670
2671 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002672 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002673 break;
2674
2675 default:
2676 memcpy(opt->val, (void *) val, len);
2677 break;
2678 }
2679
2680 *ptr += L2CAP_CONF_OPT_SIZE + len;
2681}
2682
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002683static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2684{
2685 struct l2cap_conf_efs efs;
2686
Szymon Janc1ec918c2011-11-16 09:32:21 +01002687 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002688 case L2CAP_MODE_ERTM:
2689 efs.id = chan->local_id;
2690 efs.stype = chan->local_stype;
2691 efs.msdu = cpu_to_le16(chan->local_msdu);
2692 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002693 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
2694 efs.flush_to = __constant_cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002695 break;
2696
2697 case L2CAP_MODE_STREAMING:
2698 efs.id = 1;
2699 efs.stype = L2CAP_SERV_BESTEFFORT;
2700 efs.msdu = cpu_to_le16(chan->local_msdu);
2701 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2702 efs.acc_lat = 0;
2703 efs.flush_to = 0;
2704 break;
2705
2706 default:
2707 return;
2708 }
2709
2710 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
2711 (unsigned long) &efs);
2712}
2713
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002714static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002715{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002716 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07002717 ack_timer.work);
2718 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002719
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02002720 BT_DBG("chan %p", chan);
2721
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002722 l2cap_chan_lock(chan);
2723
Mat Martineau03625202012-05-17 20:53:51 -07002724 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2725 chan->last_acked_seq);
2726
2727 if (frames_to_ack)
2728 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002729
2730 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01002731 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002732}
2733
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03002734int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002735{
Mat Martineau3c588192012-04-11 10:48:42 -07002736 int err;
2737
Mat Martineau105bdf92012-04-27 16:50:48 -07002738 chan->next_tx_seq = 0;
2739 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002740 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002741 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002742 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002743 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07002744 chan->last_acked_seq = 0;
2745 chan->sdu = NULL;
2746 chan->sdu_last_frag = NULL;
2747 chan->sdu_len = 0;
2748
Mat Martineaud34c34f2012-05-14 14:49:27 -07002749 skb_queue_head_init(&chan->tx_q);
2750
Mat Martineau105bdf92012-04-27 16:50:48 -07002751 if (chan->mode != L2CAP_MODE_ERTM)
2752 return 0;
2753
2754 chan->rx_state = L2CAP_RX_STATE_RECV;
2755 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002756
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002757 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
2758 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
2759 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002760
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03002761 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002762
Mat Martineau3c588192012-04-11 10:48:42 -07002763 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
2764 if (err < 0)
2765 return err;
2766
Mat Martineau9dc9aff2012-05-17 16:20:14 -07002767 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
2768 if (err < 0)
2769 l2cap_seq_list_free(&chan->srej_list);
2770
2771 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002772}
2773
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002774static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2775{
2776 switch (mode) {
2777 case L2CAP_MODE_STREAMING:
2778 case L2CAP_MODE_ERTM:
2779 if (l2cap_mode_supported(mode, remote_feat_mask))
2780 return mode;
2781 /* fall through */
2782 default:
2783 return L2CAP_MODE_BASIC;
2784 }
2785}
2786
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002787static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
2788{
2789 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
2790}
2791
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002792static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
2793{
2794 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
2795}
2796
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002797static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
2798{
2799 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002800 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002801 /* use extended control field */
2802 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002803 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
2804 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002805 chan->tx_win = min_t(u16, chan->tx_win,
2806 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002807 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
2808 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07002809 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002810}
2811
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03002812static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002813{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002814 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002815 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002816 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002817 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002818
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03002819 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002820
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002821 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002822 goto done;
2823
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002824 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002825 case L2CAP_MODE_STREAMING:
2826 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002827 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002828 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002829
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002830 if (__l2cap_efs_supported(chan))
2831 set_bit(FLAG_EFS_ENABLE, &chan->flags);
2832
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002833 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002834 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002835 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002836 break;
2837 }
2838
2839done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002840 if (chan->imtu != L2CAP_DEFAULT_MTU)
2841 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02002842
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002843 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002844 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002845 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
2846 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002847 break;
2848
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002849 rfc.mode = L2CAP_MODE_BASIC;
2850 rfc.txwin_size = 0;
2851 rfc.max_transmit = 0;
2852 rfc.retrans_timeout = 0;
2853 rfc.monitor_timeout = 0;
2854 rfc.max_pdu_size = 0;
2855
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002856 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2857 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002858 break;
2859
2860 case L2CAP_MODE_ERTM:
2861 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002862 rfc.max_transmit = chan->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002863 rfc.retrans_timeout = 0;
2864 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002865
2866 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
2867 L2CAP_EXT_HDR_SIZE -
2868 L2CAP_SDULEN_SIZE -
2869 L2CAP_FCS_SIZE);
2870 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002871
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002872 l2cap_txwin_setup(chan);
2873
2874 rfc.txwin_size = min_t(u16, chan->tx_win,
2875 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002876
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002877 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2878 (unsigned long) &rfc);
2879
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002880 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2881 l2cap_add_opt_efs(&ptr, chan);
2882
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002883 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002884 break;
2885
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002886 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002887 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002888 chan->fcs = L2CAP_FCS_NONE;
2889 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002890 }
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002891
2892 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2893 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
2894 chan->tx_win);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002895 break;
2896
2897 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07002898 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002899 rfc.mode = L2CAP_MODE_STREAMING;
2900 rfc.txwin_size = 0;
2901 rfc.max_transmit = 0;
2902 rfc.retrans_timeout = 0;
2903 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002904
2905 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
2906 L2CAP_EXT_HDR_SIZE -
2907 L2CAP_SDULEN_SIZE -
2908 L2CAP_FCS_SIZE);
2909 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002910
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002911 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2912 (unsigned long) &rfc);
2913
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002914 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2915 l2cap_add_opt_efs(&ptr, chan);
2916
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002917 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002918 break;
2919
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002920 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002921 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002922 chan->fcs = L2CAP_FCS_NONE;
2923 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002924 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002925 break;
2926 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002928 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03002929 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002930
2931 return ptr - data;
2932}
2933
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002934static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002935{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002936 struct l2cap_conf_rsp *rsp = data;
2937 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002938 void *req = chan->conf_req;
2939 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002940 int type, hint, olen;
2941 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002942 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002943 struct l2cap_conf_efs efs;
2944 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02002945 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002946 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002947 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002948
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002949 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002950
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002951 while (len >= L2CAP_CONF_OPT_SIZE) {
2952 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002954 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002955 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002956
2957 switch (type) {
2958 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002959 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002960 break;
2961
2962 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002963 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002964 break;
2965
2966 case L2CAP_CONF_QOS:
2967 break;
2968
Marcel Holtmann6464f352007-10-20 13:39:51 +02002969 case L2CAP_CONF_RFC:
2970 if (olen == sizeof(rfc))
2971 memcpy(&rfc, (void *) val, olen);
2972 break;
2973
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002974 case L2CAP_CONF_FCS:
2975 if (val == L2CAP_FCS_NONE)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002976 set_bit(CONF_NO_FCS_RECV, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002977 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002978
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002979 case L2CAP_CONF_EFS:
2980 remote_efs = 1;
2981 if (olen == sizeof(efs))
2982 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002983 break;
2984
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002985 case L2CAP_CONF_EWS:
2986 if (!enable_hs)
2987 return -ECONNREFUSED;
2988
2989 set_bit(FLAG_EXT_CTRL, &chan->flags);
2990 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002991 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002992 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002993 break;
2994
2995 default:
2996 if (hint)
2997 break;
2998
2999 result = L2CAP_CONF_UNKNOWN;
3000 *((u8 *) ptr++) = type;
3001 break;
3002 }
3003 }
3004
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003005 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003006 goto done;
3007
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003008 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003009 case L2CAP_MODE_STREAMING:
3010 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003011 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003012 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003013 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003014 break;
3015 }
3016
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003017 if (remote_efs) {
3018 if (__l2cap_efs_supported(chan))
3019 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3020 else
3021 return -ECONNREFUSED;
3022 }
3023
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003024 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003025 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003026
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003027 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003028 }
3029
3030done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003031 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003032 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003033 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003034
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003035 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003036 return -ECONNREFUSED;
3037
3038 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3039 sizeof(rfc), (unsigned long) &rfc);
3040 }
3041
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003042 if (result == L2CAP_CONF_SUCCESS) {
3043 /* Configure output options and let the other side know
3044 * which ones we don't like. */
3045
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003046 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3047 result = L2CAP_CONF_UNACCEPT;
3048 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003049 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003050 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003051 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003052 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003053
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003054 if (remote_efs) {
3055 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
3056 efs.stype != L2CAP_SERV_NOTRAFIC &&
3057 efs.stype != chan->local_stype) {
3058
3059 result = L2CAP_CONF_UNACCEPT;
3060
3061 if (chan->num_conf_req >= 1)
3062 return -ECONNREFUSED;
3063
3064 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003065 sizeof(efs),
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003066 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003067 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003068 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003069 result = L2CAP_CONF_PENDING;
3070 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003071 }
3072 }
3073
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003074 switch (rfc.mode) {
3075 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003076 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003077 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003078 break;
3079
3080 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003081 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3082 chan->remote_tx_win = rfc.txwin_size;
3083 else
3084 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3085
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003086 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003087
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003088 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
3089 chan->conn->mtu -
3090 L2CAP_EXT_HDR_SIZE -
3091 L2CAP_SDULEN_SIZE -
3092 L2CAP_FCS_SIZE);
3093 rfc.max_pdu_size = cpu_to_le16(size);
3094 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003095
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003096 rfc.retrans_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003097 __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003098 rfc.monitor_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003099 __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003100
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003101 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003102
3103 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3104 sizeof(rfc), (unsigned long) &rfc);
3105
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003106 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3107 chan->remote_id = efs.id;
3108 chan->remote_stype = efs.stype;
3109 chan->remote_msdu = le16_to_cpu(efs.msdu);
3110 chan->remote_flush_to =
3111 le32_to_cpu(efs.flush_to);
3112 chan->remote_acc_lat =
3113 le32_to_cpu(efs.acc_lat);
3114 chan->remote_sdu_itime =
3115 le32_to_cpu(efs.sdu_itime);
3116 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
3117 sizeof(efs), (unsigned long) &efs);
3118 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003119 break;
3120
3121 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003122 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
3123 chan->conn->mtu -
3124 L2CAP_EXT_HDR_SIZE -
3125 L2CAP_SDULEN_SIZE -
3126 L2CAP_FCS_SIZE);
3127 rfc.max_pdu_size = cpu_to_le16(size);
3128 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003129
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003130 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003131
3132 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3133 sizeof(rfc), (unsigned long) &rfc);
3134
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003135 break;
3136
3137 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003138 result = L2CAP_CONF_UNACCEPT;
3139
3140 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003141 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003142 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003143
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003144 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003145 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003146 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003147 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003148 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003149 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003150
3151 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003152}
3153
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003154static 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 -03003155{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003156 struct l2cap_conf_req *req = data;
3157 void *ptr = req->data;
3158 int type, olen;
3159 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003160 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003161 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003162
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003163 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003164
3165 while (len >= L2CAP_CONF_OPT_SIZE) {
3166 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3167
3168 switch (type) {
3169 case L2CAP_CONF_MTU:
3170 if (val < L2CAP_DEFAULT_MIN_MTU) {
3171 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003172 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003173 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003174 chan->imtu = val;
3175 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003176 break;
3177
3178 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003179 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003180 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003181 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003182 break;
3183
3184 case L2CAP_CONF_RFC:
3185 if (olen == sizeof(rfc))
3186 memcpy(&rfc, (void *)val, olen);
3187
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003188 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003189 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003190 return -ECONNREFUSED;
3191
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003192 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003193
3194 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3195 sizeof(rfc), (unsigned long) &rfc);
3196 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003197
3198 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003199 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003200 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003201 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003202 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003203
3204 case L2CAP_CONF_EFS:
3205 if (olen == sizeof(efs))
3206 memcpy(&efs, (void *)val, olen);
3207
3208 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
3209 efs.stype != L2CAP_SERV_NOTRAFIC &&
3210 efs.stype != chan->local_stype)
3211 return -ECONNREFUSED;
3212
3213 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
3214 sizeof(efs), (unsigned long) &efs);
3215 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003216 }
3217 }
3218
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003219 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003220 return -ECONNREFUSED;
3221
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003222 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003223
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003224 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003225 switch (rfc.mode) {
3226 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003227 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3228 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3229 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003230 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3231 chan->ack_win = min_t(u16, chan->ack_win,
3232 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003233
3234 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3235 chan->local_msdu = le16_to_cpu(efs.msdu);
3236 chan->local_sdu_itime =
3237 le32_to_cpu(efs.sdu_itime);
3238 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3239 chan->local_flush_to =
3240 le32_to_cpu(efs.flush_to);
3241 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003242 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003243
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003244 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003245 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003246 }
3247 }
3248
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003249 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003250 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003251
3252 return ptr - data;
3253}
3254
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003255static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003256{
3257 struct l2cap_conf_rsp *rsp = data;
3258 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003259
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003260 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003261
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003262 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003263 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003264 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003265
3266 return ptr - data;
3267}
3268
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003269void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003270{
3271 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003272 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003273 u8 buf[128];
3274
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003275 rsp.scid = cpu_to_le16(chan->dcid);
3276 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003277 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3278 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003279 l2cap_send_cmd(conn, chan->ident,
3280 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
3281
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003282 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003283 return;
3284
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003285 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3286 l2cap_build_conf_req(chan, buf), buf);
3287 chan->num_conf_req++;
3288}
3289
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003290static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003291{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003292 int type, olen;
3293 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003294 /* Use sane default values in case a misbehaving remote device
3295 * did not send an RFC or extended window size option.
3296 */
3297 u16 txwin_ext = chan->ack_win;
3298 struct l2cap_conf_rfc rfc = {
3299 .mode = chan->mode,
3300 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3301 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3302 .max_pdu_size = cpu_to_le16(chan->imtu),
3303 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3304 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003305
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003306 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003307
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003308 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003309 return;
3310
3311 while (len >= L2CAP_CONF_OPT_SIZE) {
3312 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3313
Mat Martineauc20f8e32012-07-10 05:47:07 -07003314 switch (type) {
3315 case L2CAP_CONF_RFC:
3316 if (olen == sizeof(rfc))
3317 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003318 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003319 case L2CAP_CONF_EWS:
3320 txwin_ext = val;
3321 break;
3322 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003323 }
3324
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003325 switch (rfc.mode) {
3326 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003327 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3328 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003329 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3330 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3331 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3332 else
3333 chan->ack_win = min_t(u16, chan->ack_win,
3334 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003335 break;
3336 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003337 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003338 }
3339}
3340
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003341static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3342{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003343 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003344
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003345 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003346 return 0;
3347
3348 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
3349 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003350 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003351
3352 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003353 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003354
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003355 l2cap_conn_start(conn);
3356 }
3357
3358 return 0;
3359}
3360
Linus Torvalds1da177e2005-04-16 15:20:36 -07003361static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3362{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003363 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3364 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003365 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003366 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003367 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003368
3369 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003370 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003371
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003372 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003373
3374 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003375 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003376 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003377 result = L2CAP_CR_BAD_PSM;
3378 goto sendresp;
3379 }
3380
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003381 parent = pchan->sk;
3382
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003383 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003384 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003385
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003386 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003387 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003388 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003389 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003390 result = L2CAP_CR_SEC_BLOCK;
3391 goto response;
3392 }
3393
Linus Torvalds1da177e2005-04-16 15:20:36 -07003394 result = L2CAP_CR_NO_MEM;
3395
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003396 /* Check if we already have channel with that dcid */
3397 if (__l2cap_get_chan_by_dcid(conn, scid))
3398 goto response;
3399
Gustavo Padovan80b98022012-05-27 22:27:51 -03003400 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003401 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003402 goto response;
3403
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003404 sk = chan->sk;
3405
Linus Torvalds1da177e2005-04-16 15:20:36 -07003406 hci_conn_hold(conn->hcon);
3407
Linus Torvalds1da177e2005-04-16 15:20:36 -07003408 bacpy(&bt_sk(sk)->src, conn->src);
3409 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003410 chan->psm = psm;
3411 chan->dcid = scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003412
Gustavo F. Padovand1010242011-03-25 00:39:48 -03003413 bt_accept_enqueue(parent, sk);
3414
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003415 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003416
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003417 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003418
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003419 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003420
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003421 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003422
Marcel Holtmann984947d2009-02-06 23:35:19 +01003423 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003424 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003425 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003426 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003427 result = L2CAP_CR_PEND;
3428 status = L2CAP_CS_AUTHOR_PEND;
3429 parent->sk_data_ready(parent, 0);
3430 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003431 __l2cap_state_change(chan, BT_CONFIG);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003432 result = L2CAP_CR_SUCCESS;
3433 status = L2CAP_CS_NO_INFO;
3434 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003435 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003436 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003437 result = L2CAP_CR_PEND;
3438 status = L2CAP_CS_AUTHEN_PEND;
3439 }
3440 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003441 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003442 result = L2CAP_CR_PEND;
3443 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003444 }
3445
Linus Torvalds1da177e2005-04-16 15:20:36 -07003446response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003447 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003448 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003449
3450sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003451 rsp.scid = cpu_to_le16(scid);
3452 rsp.dcid = cpu_to_le16(dcid);
3453 rsp.result = cpu_to_le16(result);
3454 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003455 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003456
3457 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3458 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003459 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003460
3461 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3462 conn->info_ident = l2cap_get_ident(conn);
3463
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003464 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003465
3466 l2cap_send_cmd(conn, conn->info_ident,
3467 L2CAP_INFO_REQ, sizeof(info), &info);
3468 }
3469
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003470 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003471 result == L2CAP_CR_SUCCESS) {
3472 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003473 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003474 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003475 l2cap_build_conf_req(chan, buf), buf);
3476 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003477 }
3478
Linus Torvalds1da177e2005-04-16 15:20:36 -07003479 return 0;
3480}
3481
3482static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3483{
3484 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3485 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003486 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003487 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003488 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003489
3490 scid = __le16_to_cpu(rsp->scid);
3491 dcid = __le16_to_cpu(rsp->dcid);
3492 result = __le16_to_cpu(rsp->result);
3493 status = __le16_to_cpu(rsp->status);
3494
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003495 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x",
3496 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003497
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003498 mutex_lock(&conn->chan_lock);
3499
Linus Torvalds1da177e2005-04-16 15:20:36 -07003500 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003501 chan = __l2cap_get_chan_by_scid(conn, scid);
3502 if (!chan) {
3503 err = -EFAULT;
3504 goto unlock;
3505 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003506 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003507 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3508 if (!chan) {
3509 err = -EFAULT;
3510 goto unlock;
3511 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003512 }
3513
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003514 err = 0;
3515
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003516 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003517
Linus Torvalds1da177e2005-04-16 15:20:36 -07003518 switch (result) {
3519 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003520 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003521 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003522 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003523 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003524
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003525 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003526 break;
3527
Linus Torvalds1da177e2005-04-16 15:20:36 -07003528 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003529 l2cap_build_conf_req(chan, req), req);
3530 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003531 break;
3532
3533 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003534 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003535 break;
3536
3537 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003538 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003539 break;
3540 }
3541
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003542 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003543
3544unlock:
3545 mutex_unlock(&conn->chan_lock);
3546
3547 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003548}
3549
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003550static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003551{
3552 /* FCS is enabled only in ERTM or streaming mode, if one or both
3553 * sides request it.
3554 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003555 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003556 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003557 else if (!test_bit(CONF_NO_FCS_RECV, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003558 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003559}
3560
Al Viro88219a02007-07-29 00:17:25 -07003561static 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 -07003562{
3563 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3564 u16 dcid, flags;
3565 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003566 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003567 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003568
3569 dcid = __le16_to_cpu(req->dcid);
3570 flags = __le16_to_cpu(req->flags);
3571
3572 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3573
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003574 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003575 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003576 return -ENOENT;
3577
David S. Miller033b1142011-07-21 13:38:42 -07003578 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003579 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003580
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003581 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003582 rej.scid = cpu_to_le16(chan->scid);
3583 rej.dcid = cpu_to_le16(chan->dcid);
3584
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003585 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
3586 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003587 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003588 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003589
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003590 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003591 len = cmd_len - sizeof(*req);
Dan Rosenberg7ac28812011-06-24 08:38:05 -04003592 if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003593 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003594 l2cap_build_conf_rsp(chan, rsp,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003595 L2CAP_CONF_REJECT, flags), rsp);
3596 goto unlock;
3597 }
3598
3599 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003600 memcpy(chan->conf_req + chan->conf_len, req->data, len);
3601 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003602
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003603 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003604 /* Incomplete config. Send empty response. */
3605 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003606 l2cap_build_conf_rsp(chan, rsp,
Andrei Emeltchenko5325e5b2012-05-23 11:31:22 +03003607 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003608 goto unlock;
3609 }
3610
3611 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003612 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003613 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003614 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003615 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003616 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003617
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003618 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003619 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003620
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003621 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003622 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003623
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003624 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02003625 goto unlock;
3626
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003627 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003628 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003629
Mat Martineau105bdf92012-04-27 16:50:48 -07003630 if (chan->mode == L2CAP_MODE_ERTM ||
3631 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003632 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003633
Mat Martineau3c588192012-04-11 10:48:42 -07003634 if (err < 0)
3635 l2cap_send_disconn_req(chan->conn, chan, -err);
3636 else
3637 l2cap_chan_ready(chan);
3638
Marcel Holtmann876d9482007-10-20 13:35:42 +02003639 goto unlock;
3640 }
3641
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003642 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003643 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003644 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003645 l2cap_build_conf_req(chan, buf), buf);
3646 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003647 }
3648
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003649 /* Got Conf Rsp PENDING from remote side and asume we sent
3650 Conf Rsp PENDING in the code above */
3651 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
3652 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3653
3654 /* check compatibility */
3655
3656 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3657 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3658
3659 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003660 l2cap_build_conf_rsp(chan, rsp,
Andrei Emeltchenko5325e5b2012-05-23 11:31:22 +03003661 L2CAP_CONF_SUCCESS, flags), rsp);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003662 }
3663
Linus Torvalds1da177e2005-04-16 15:20:36 -07003664unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003665 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003666 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003667}
3668
3669static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3670{
3671 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3672 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003673 struct l2cap_chan *chan;
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003674 int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07003675 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003676
3677 scid = __le16_to_cpu(rsp->scid);
3678 flags = __le16_to_cpu(rsp->flags);
3679 result = __le16_to_cpu(rsp->result);
3680
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003681 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
3682 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003683
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003684 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003685 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003686 return 0;
3687
3688 switch (result) {
3689 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003690 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003691 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003692 break;
3693
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003694 case L2CAP_CONF_PENDING:
3695 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
3696
3697 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3698 char buf[64];
3699
3700 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3701 buf, &result);
3702 if (len < 0) {
3703 l2cap_send_disconn_req(conn, chan, ECONNRESET);
3704 goto done;
3705 }
3706
3707 /* check compatibility */
3708
3709 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3710 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3711
3712 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003713 l2cap_build_conf_rsp(chan, buf,
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003714 L2CAP_CONF_SUCCESS, 0x0000), buf);
3715 }
3716 goto done;
3717
Linus Torvalds1da177e2005-04-16 15:20:36 -07003718 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003719 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003720 char req[64];
3721
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003722 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003723 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003724 goto done;
3725 }
3726
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003727 /* throw out any old stored conf requests */
3728 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003729 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3730 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003731 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003732 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003733 goto done;
3734 }
3735
3736 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3737 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003738 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003739 if (result != L2CAP_CONF_SUCCESS)
3740 goto done;
3741 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003742 }
3743
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003744 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003745 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02003746
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003747 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003748 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003749 goto done;
3750 }
3751
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003752 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003753 goto done;
3754
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003755 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003756
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003757 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003758 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003759
Mat Martineau105bdf92012-04-27 16:50:48 -07003760 if (chan->mode == L2CAP_MODE_ERTM ||
3761 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003762 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003763
Mat Martineau3c588192012-04-11 10:48:42 -07003764 if (err < 0)
3765 l2cap_send_disconn_req(chan->conn, chan, -err);
3766 else
3767 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003768 }
3769
3770done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003771 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003772 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003773}
3774
3775static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3776{
3777 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3778 struct l2cap_disconn_rsp rsp;
3779 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003780 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003781 struct sock *sk;
3782
3783 scid = __le16_to_cpu(req->scid);
3784 dcid = __le16_to_cpu(req->dcid);
3785
3786 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3787
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003788 mutex_lock(&conn->chan_lock);
3789
3790 chan = __l2cap_get_chan_by_scid(conn, dcid);
3791 if (!chan) {
3792 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003793 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003794 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003795
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003796 l2cap_chan_lock(chan);
3797
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003798 sk = chan->sk;
3799
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003800 rsp.dcid = cpu_to_le16(chan->scid);
3801 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003802 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3803
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003804 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003805 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003806 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003807
Mat Martineau61d6ef32012-04-27 16:50:50 -07003808 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003809 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003810
3811 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003812
Gustavo Padovan80b98022012-05-27 22:27:51 -03003813 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003814 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003815
3816 mutex_unlock(&conn->chan_lock);
3817
Linus Torvalds1da177e2005-04-16 15:20:36 -07003818 return 0;
3819}
3820
3821static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3822{
3823 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3824 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003825 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003826
3827 scid = __le16_to_cpu(rsp->scid);
3828 dcid = __le16_to_cpu(rsp->dcid);
3829
3830 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3831
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003832 mutex_lock(&conn->chan_lock);
3833
3834 chan = __l2cap_get_chan_by_scid(conn, scid);
3835 if (!chan) {
3836 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003837 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003838 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003839
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003840 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003841
Mat Martineau61d6ef32012-04-27 16:50:50 -07003842 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003843 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003844
3845 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003846
Gustavo Padovan80b98022012-05-27 22:27:51 -03003847 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003848 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003849
3850 mutex_unlock(&conn->chan_lock);
3851
Linus Torvalds1da177e2005-04-16 15:20:36 -07003852 return 0;
3853}
3854
3855static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3856{
3857 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003858 u16 type;
3859
3860 type = __le16_to_cpu(req->type);
3861
3862 BT_DBG("type 0x%4.4x", type);
3863
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003864 if (type == L2CAP_IT_FEAT_MASK) {
3865 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003866 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003867 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003868 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
3869 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03003870 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003871 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3872 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003873 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003874 feat_mask |= L2CAP_FEAT_EXT_FLOW
3875 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003876
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003877 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003878 l2cap_send_cmd(conn, cmd->ident,
3879 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003880 } else if (type == L2CAP_IT_FIXED_CHAN) {
3881 u8 buf[12];
3882 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07003883
3884 if (enable_hs)
3885 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
3886 else
3887 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
3888
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003889 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3890 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03003891 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003892 l2cap_send_cmd(conn, cmd->ident,
3893 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003894 } else {
3895 struct l2cap_info_rsp rsp;
3896 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003897 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003898 l2cap_send_cmd(conn, cmd->ident,
3899 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3900 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003901
3902 return 0;
3903}
3904
3905static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3906{
3907 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3908 u16 type, result;
3909
3910 type = __le16_to_cpu(rsp->type);
3911 result = __le16_to_cpu(rsp->result);
3912
3913 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3914
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02003915 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
3916 if (cmd->ident != conn->info_ident ||
3917 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
3918 return 0;
3919
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003920 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003921
Ville Tervoadb08ed2010-08-04 09:43:33 +03003922 if (result != L2CAP_IR_SUCCESS) {
3923 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3924 conn->info_ident = 0;
3925
3926 l2cap_conn_start(conn);
3927
3928 return 0;
3929 }
3930
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003931 switch (type) {
3932 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07003933 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003934
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003935 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003936 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003937 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003938
3939 conn->info_ident = l2cap_get_ident(conn);
3940
3941 l2cap_send_cmd(conn, conn->info_ident,
3942 L2CAP_INFO_REQ, sizeof(req), &req);
3943 } else {
3944 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3945 conn->info_ident = 0;
3946
3947 l2cap_conn_start(conn);
3948 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003949 break;
3950
3951 case L2CAP_IT_FIXED_CHAN:
3952 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01003953 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003954 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003955
3956 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003957 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003958 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003959
Linus Torvalds1da177e2005-04-16 15:20:36 -07003960 return 0;
3961}
3962
Mat Martineauf94ff6f2011-11-02 16:18:32 -07003963static inline int l2cap_create_channel_req(struct l2cap_conn *conn,
3964 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3965 void *data)
3966{
3967 struct l2cap_create_chan_req *req = data;
3968 struct l2cap_create_chan_rsp rsp;
3969 u16 psm, scid;
3970
3971 if (cmd_len != sizeof(*req))
3972 return -EPROTO;
3973
3974 if (!enable_hs)
3975 return -EINVAL;
3976
3977 psm = le16_to_cpu(req->psm);
3978 scid = le16_to_cpu(req->scid);
3979
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03003980 BT_DBG("psm 0x%2.2x, scid 0x%4.4x, amp_id %d", psm, scid, req->amp_id);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07003981
3982 /* Placeholder: Always reject */
3983 rsp.dcid = 0;
3984 rsp.scid = cpu_to_le16(scid);
Andrei Emeltchenko8ce0c492012-03-12 12:13:09 +02003985 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
3986 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07003987
3988 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
3989 sizeof(rsp), &rsp);
3990
3991 return 0;
3992}
3993
3994static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn,
3995 struct l2cap_cmd_hdr *cmd, void *data)
3996{
3997 BT_DBG("conn %p", conn);
3998
3999 return l2cap_connect_rsp(conn, cmd, data);
4000}
4001
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004002static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004003 u16 icid, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004004{
4005 struct l2cap_move_chan_rsp rsp;
4006
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004007 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004008
4009 rsp.icid = cpu_to_le16(icid);
4010 rsp.result = cpu_to_le16(result);
4011
4012 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_RSP, sizeof(rsp), &rsp);
4013}
4014
4015static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004016 struct l2cap_chan *chan,
4017 u16 icid, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004018{
4019 struct l2cap_move_chan_cfm cfm;
4020 u8 ident;
4021
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004022 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004023
4024 ident = l2cap_get_ident(conn);
4025 if (chan)
4026 chan->ident = ident;
4027
4028 cfm.icid = cpu_to_le16(icid);
4029 cfm.result = cpu_to_le16(result);
4030
4031 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM, sizeof(cfm), &cfm);
4032}
4033
4034static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004035 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004036{
4037 struct l2cap_move_chan_cfm_rsp rsp;
4038
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004039 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004040
4041 rsp.icid = cpu_to_le16(icid);
4042 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4043}
4044
4045static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004046 struct l2cap_cmd_hdr *cmd,
4047 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004048{
4049 struct l2cap_move_chan_req *req = data;
4050 u16 icid = 0;
4051 u16 result = L2CAP_MR_NOT_ALLOWED;
4052
4053 if (cmd_len != sizeof(*req))
4054 return -EPROTO;
4055
4056 icid = le16_to_cpu(req->icid);
4057
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004058 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004059
4060 if (!enable_hs)
4061 return -EINVAL;
4062
4063 /* Placeholder: Always refuse */
4064 l2cap_send_move_chan_rsp(conn, cmd->ident, icid, result);
4065
4066 return 0;
4067}
4068
4069static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004070 struct l2cap_cmd_hdr *cmd,
4071 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004072{
4073 struct l2cap_move_chan_rsp *rsp = data;
4074 u16 icid, result;
4075
4076 if (cmd_len != sizeof(*rsp))
4077 return -EPROTO;
4078
4079 icid = le16_to_cpu(rsp->icid);
4080 result = le16_to_cpu(rsp->result);
4081
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004082 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004083
4084 /* Placeholder: Always unconfirmed */
4085 l2cap_send_move_chan_cfm(conn, NULL, icid, L2CAP_MC_UNCONFIRMED);
4086
4087 return 0;
4088}
4089
4090static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004091 struct l2cap_cmd_hdr *cmd,
4092 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004093{
4094 struct l2cap_move_chan_cfm *cfm = data;
4095 u16 icid, result;
4096
4097 if (cmd_len != sizeof(*cfm))
4098 return -EPROTO;
4099
4100 icid = le16_to_cpu(cfm->icid);
4101 result = le16_to_cpu(cfm->result);
4102
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004103 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004104
4105 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4106
4107 return 0;
4108}
4109
4110static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004111 struct l2cap_cmd_hdr *cmd,
4112 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004113{
4114 struct l2cap_move_chan_cfm_rsp *rsp = data;
4115 u16 icid;
4116
4117 if (cmd_len != sizeof(*rsp))
4118 return -EPROTO;
4119
4120 icid = le16_to_cpu(rsp->icid);
4121
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004122 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004123
4124 return 0;
4125}
4126
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004127static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Claudio Takahaside731152011-02-11 19:28:55 -02004128 u16 to_multiplier)
4129{
4130 u16 max_latency;
4131
4132 if (min > max || min < 6 || max > 3200)
4133 return -EINVAL;
4134
4135 if (to_multiplier < 10 || to_multiplier > 3200)
4136 return -EINVAL;
4137
4138 if (max >= to_multiplier * 8)
4139 return -EINVAL;
4140
4141 max_latency = (to_multiplier * 8 / max) - 1;
4142 if (latency > 499 || latency > max_latency)
4143 return -EINVAL;
4144
4145 return 0;
4146}
4147
4148static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
4149 struct l2cap_cmd_hdr *cmd, u8 *data)
4150{
4151 struct hci_conn *hcon = conn->hcon;
4152 struct l2cap_conn_param_update_req *req;
4153 struct l2cap_conn_param_update_rsp rsp;
4154 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004155 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02004156
4157 if (!(hcon->link_mode & HCI_LM_MASTER))
4158 return -EINVAL;
4159
4160 cmd_len = __le16_to_cpu(cmd->len);
4161 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
4162 return -EPROTO;
4163
4164 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004165 min = __le16_to_cpu(req->min);
4166 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02004167 latency = __le16_to_cpu(req->latency);
4168 to_multiplier = __le16_to_cpu(req->to_multiplier);
4169
4170 BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
4171 min, max, latency, to_multiplier);
4172
4173 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004174
4175 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
4176 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004177 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004178 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004179 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004180
4181 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
4182 sizeof(rsp), &rsp);
4183
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004184 if (!err)
4185 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
4186
Claudio Takahaside731152011-02-11 19:28:55 -02004187 return 0;
4188}
4189
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004190static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
4191 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
4192{
4193 int err = 0;
4194
4195 switch (cmd->code) {
4196 case L2CAP_COMMAND_REJ:
4197 l2cap_command_rej(conn, cmd, data);
4198 break;
4199
4200 case L2CAP_CONN_REQ:
4201 err = l2cap_connect_req(conn, cmd, data);
4202 break;
4203
4204 case L2CAP_CONN_RSP:
4205 err = l2cap_connect_rsp(conn, cmd, data);
4206 break;
4207
4208 case L2CAP_CONF_REQ:
4209 err = l2cap_config_req(conn, cmd, cmd_len, data);
4210 break;
4211
4212 case L2CAP_CONF_RSP:
4213 err = l2cap_config_rsp(conn, cmd, data);
4214 break;
4215
4216 case L2CAP_DISCONN_REQ:
4217 err = l2cap_disconnect_req(conn, cmd, data);
4218 break;
4219
4220 case L2CAP_DISCONN_RSP:
4221 err = l2cap_disconnect_rsp(conn, cmd, data);
4222 break;
4223
4224 case L2CAP_ECHO_REQ:
4225 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
4226 break;
4227
4228 case L2CAP_ECHO_RSP:
4229 break;
4230
4231 case L2CAP_INFO_REQ:
4232 err = l2cap_information_req(conn, cmd, data);
4233 break;
4234
4235 case L2CAP_INFO_RSP:
4236 err = l2cap_information_rsp(conn, cmd, data);
4237 break;
4238
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004239 case L2CAP_CREATE_CHAN_REQ:
4240 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
4241 break;
4242
4243 case L2CAP_CREATE_CHAN_RSP:
4244 err = l2cap_create_channel_rsp(conn, cmd, data);
4245 break;
4246
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004247 case L2CAP_MOVE_CHAN_REQ:
4248 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
4249 break;
4250
4251 case L2CAP_MOVE_CHAN_RSP:
4252 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
4253 break;
4254
4255 case L2CAP_MOVE_CHAN_CFM:
4256 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
4257 break;
4258
4259 case L2CAP_MOVE_CHAN_CFM_RSP:
4260 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
4261 break;
4262
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004263 default:
4264 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
4265 err = -EINVAL;
4266 break;
4267 }
4268
4269 return err;
4270}
4271
4272static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
4273 struct l2cap_cmd_hdr *cmd, u8 *data)
4274{
4275 switch (cmd->code) {
4276 case L2CAP_COMMAND_REJ:
4277 return 0;
4278
4279 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02004280 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004281
4282 case L2CAP_CONN_PARAM_UPDATE_RSP:
4283 return 0;
4284
4285 default:
4286 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
4287 return -EINVAL;
4288 }
4289}
4290
4291static inline void l2cap_sig_channel(struct l2cap_conn *conn,
4292 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004293{
4294 u8 *data = skb->data;
4295 int len = skb->len;
4296 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004297 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004298
4299 l2cap_raw_recv(conn, skb);
4300
4301 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07004302 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004303 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
4304 data += L2CAP_CMD_HDR_SIZE;
4305 len -= L2CAP_CMD_HDR_SIZE;
4306
Al Viro88219a02007-07-29 00:17:25 -07004307 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004308
Al Viro88219a02007-07-29 00:17:25 -07004309 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 -07004310
Al Viro88219a02007-07-29 00:17:25 -07004311 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004312 BT_DBG("corrupted command");
4313 break;
4314 }
4315
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004316 if (conn->hcon->type == LE_LINK)
4317 err = l2cap_le_sig_cmd(conn, &cmd, data);
4318 else
4319 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004320
4321 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004322 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03004323
4324 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004325
4326 /* FIXME: Map err to a valid reason */
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004327 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004328 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
4329 }
4330
Al Viro88219a02007-07-29 00:17:25 -07004331 data += cmd_len;
4332 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004333 }
4334
4335 kfree_skb(skb);
4336}
4337
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004338static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004339{
4340 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03004341 int hdr_size;
4342
4343 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
4344 hdr_size = L2CAP_EXT_HDR_SIZE;
4345 else
4346 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004347
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004348 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004349 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004350 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
4351 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
4352
4353 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03004354 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004355 }
4356 return 0;
4357}
4358
Mat Martineau6ea00482012-05-17 20:53:52 -07004359static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004360{
Mat Martineaue31f7632012-05-17 20:53:41 -07004361 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004362
Mat Martineaue31f7632012-05-17 20:53:41 -07004363 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004364
Mat Martineaue31f7632012-05-17 20:53:41 -07004365 memset(&control, 0, sizeof(control));
4366 control.sframe = 1;
4367 control.final = 1;
4368 control.reqseq = chan->buffer_seq;
4369 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004370
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004371 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07004372 control.super = L2CAP_SUPER_RNR;
4373 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004374 }
4375
Mat Martineaue31f7632012-05-17 20:53:41 -07004376 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
4377 chan->unacked_frames > 0)
4378 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004379
Mat Martineaue31f7632012-05-17 20:53:41 -07004380 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03004381 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004382
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004383 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07004384 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
4385 /* F-bit wasn't sent in an s-frame or i-frame yet, so
4386 * send it now.
4387 */
4388 control.super = L2CAP_SUPER_RR;
4389 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004390 }
4391}
4392
Mat Martineau84084a32011-07-22 14:54:00 -07004393static void append_skb_frag(struct sk_buff *skb,
4394 struct sk_buff *new_frag, struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004395{
Mat Martineau84084a32011-07-22 14:54:00 -07004396 /* skb->len reflects data in skb as well as all fragments
4397 * skb->data_len reflects only data in fragments
4398 */
4399 if (!skb_has_frag_list(skb))
4400 skb_shinfo(skb)->frag_list = new_frag;
4401
4402 new_frag->next = NULL;
4403
4404 (*last_frag)->next = new_frag;
4405 *last_frag = new_frag;
4406
4407 skb->len += new_frag->len;
4408 skb->data_len += new_frag->len;
4409 skb->truesize += new_frag->truesize;
4410}
4411
Mat Martineau4b51dae92012-05-17 20:53:37 -07004412static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
4413 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07004414{
4415 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004416
Mat Martineau4b51dae92012-05-17 20:53:37 -07004417 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004418 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07004419 if (chan->sdu)
4420 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004421
Gustavo Padovan80b98022012-05-27 22:27:51 -03004422 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07004423 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004424
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004425 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07004426 if (chan->sdu)
4427 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004428
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004429 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004430 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004431
Mat Martineau84084a32011-07-22 14:54:00 -07004432 if (chan->sdu_len > chan->imtu) {
4433 err = -EMSGSIZE;
4434 break;
4435 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004436
Mat Martineau84084a32011-07-22 14:54:00 -07004437 if (skb->len >= chan->sdu_len)
4438 break;
4439
4440 chan->sdu = skb;
4441 chan->sdu_last_frag = skb;
4442
4443 skb = NULL;
4444 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004445 break;
4446
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004447 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004448 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004449 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004450
Mat Martineau84084a32011-07-22 14:54:00 -07004451 append_skb_frag(chan->sdu, skb,
4452 &chan->sdu_last_frag);
4453 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004454
Mat Martineau84084a32011-07-22 14:54:00 -07004455 if (chan->sdu->len >= chan->sdu_len)
4456 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004457
Mat Martineau84084a32011-07-22 14:54:00 -07004458 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004459 break;
4460
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004461 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004462 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004463 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004464
Mat Martineau84084a32011-07-22 14:54:00 -07004465 append_skb_frag(chan->sdu, skb,
4466 &chan->sdu_last_frag);
4467 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004468
Mat Martineau84084a32011-07-22 14:54:00 -07004469 if (chan->sdu->len != chan->sdu_len)
4470 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004471
Gustavo Padovan80b98022012-05-27 22:27:51 -03004472 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004473
Mat Martineau84084a32011-07-22 14:54:00 -07004474 if (!err) {
4475 /* Reassembly complete */
4476 chan->sdu = NULL;
4477 chan->sdu_last_frag = NULL;
4478 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004479 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004480 break;
4481 }
4482
Mat Martineau84084a32011-07-22 14:54:00 -07004483 if (err) {
4484 kfree_skb(skb);
4485 kfree_skb(chan->sdu);
4486 chan->sdu = NULL;
4487 chan->sdu_last_frag = NULL;
4488 chan->sdu_len = 0;
4489 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004490
Mat Martineau84084a32011-07-22 14:54:00 -07004491 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004492}
4493
Mat Martineaue3281402011-07-07 09:39:02 -07004494void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03004495{
Mat Martineau61aa4f52012-05-17 20:53:40 -07004496 u8 event;
4497
4498 if (chan->mode != L2CAP_MODE_ERTM)
4499 return;
4500
4501 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03004502 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004503}
4504
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004505static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
4506{
Mat Martineau63838722012-05-17 20:53:45 -07004507 int err = 0;
4508 /* Pass sequential frames to l2cap_reassemble_sdu()
4509 * until a gap is encountered.
4510 */
4511
4512 BT_DBG("chan %p", chan);
4513
4514 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4515 struct sk_buff *skb;
4516 BT_DBG("Searching for skb with txseq %d (queue len %d)",
4517 chan->buffer_seq, skb_queue_len(&chan->srej_q));
4518
4519 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
4520
4521 if (!skb)
4522 break;
4523
4524 skb_unlink(skb, &chan->srej_q);
4525 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
4526 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
4527 if (err)
4528 break;
4529 }
4530
4531 if (skb_queue_empty(&chan->srej_q)) {
4532 chan->rx_state = L2CAP_RX_STATE_RECV;
4533 l2cap_send_ack(chan);
4534 }
4535
4536 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004537}
4538
4539static void l2cap_handle_srej(struct l2cap_chan *chan,
4540 struct l2cap_ctrl *control)
4541{
Mat Martineauf80842a2012-05-17 20:53:46 -07004542 struct sk_buff *skb;
4543
4544 BT_DBG("chan %p, control %p", chan, control);
4545
4546 if (control->reqseq == chan->next_tx_seq) {
4547 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4548 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4549 return;
4550 }
4551
4552 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4553
4554 if (skb == NULL) {
4555 BT_DBG("Seq %d not available for retransmission",
4556 control->reqseq);
4557 return;
4558 }
4559
4560 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
4561 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4562 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4563 return;
4564 }
4565
4566 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4567
4568 if (control->poll) {
4569 l2cap_pass_to_tx(chan, control);
4570
4571 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4572 l2cap_retransmit(chan, control);
4573 l2cap_ertm_send(chan);
4574
4575 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4576 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4577 chan->srej_save_reqseq = control->reqseq;
4578 }
4579 } else {
4580 l2cap_pass_to_tx_fbit(chan, control);
4581
4582 if (control->final) {
4583 if (chan->srej_save_reqseq != control->reqseq ||
4584 !test_and_clear_bit(CONN_SREJ_ACT,
4585 &chan->conn_state))
4586 l2cap_retransmit(chan, control);
4587 } else {
4588 l2cap_retransmit(chan, control);
4589 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4590 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4591 chan->srej_save_reqseq = control->reqseq;
4592 }
4593 }
4594 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004595}
4596
4597static void l2cap_handle_rej(struct l2cap_chan *chan,
4598 struct l2cap_ctrl *control)
4599{
Mat Martineaufcd289d2012-05-17 20:53:47 -07004600 struct sk_buff *skb;
4601
4602 BT_DBG("chan %p, control %p", chan, control);
4603
4604 if (control->reqseq == chan->next_tx_seq) {
4605 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4606 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4607 return;
4608 }
4609
4610 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4611
4612 if (chan->max_tx && skb &&
4613 bt_cb(skb)->control.retries >= chan->max_tx) {
4614 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4615 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4616 return;
4617 }
4618
4619 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4620
4621 l2cap_pass_to_tx(chan, control);
4622
4623 if (control->final) {
4624 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
4625 l2cap_retransmit_all(chan, control);
4626 } else {
4627 l2cap_retransmit_all(chan, control);
4628 l2cap_ertm_send(chan);
4629 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
4630 set_bit(CONN_REJ_ACT, &chan->conn_state);
4631 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004632}
4633
Mat Martineau4b51dae92012-05-17 20:53:37 -07004634static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
4635{
4636 BT_DBG("chan %p, txseq %d", chan, txseq);
4637
4638 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
4639 chan->expected_tx_seq);
4640
4641 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
4642 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4643 chan->tx_win) {
4644 /* See notes below regarding "double poll" and
4645 * invalid packets.
4646 */
4647 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4648 BT_DBG("Invalid/Ignore - after SREJ");
4649 return L2CAP_TXSEQ_INVALID_IGNORE;
4650 } else {
4651 BT_DBG("Invalid - in window after SREJ sent");
4652 return L2CAP_TXSEQ_INVALID;
4653 }
4654 }
4655
4656 if (chan->srej_list.head == txseq) {
4657 BT_DBG("Expected SREJ");
4658 return L2CAP_TXSEQ_EXPECTED_SREJ;
4659 }
4660
4661 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
4662 BT_DBG("Duplicate SREJ - txseq already stored");
4663 return L2CAP_TXSEQ_DUPLICATE_SREJ;
4664 }
4665
4666 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
4667 BT_DBG("Unexpected SREJ - not requested");
4668 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
4669 }
4670 }
4671
4672 if (chan->expected_tx_seq == txseq) {
4673 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4674 chan->tx_win) {
4675 BT_DBG("Invalid - txseq outside tx window");
4676 return L2CAP_TXSEQ_INVALID;
4677 } else {
4678 BT_DBG("Expected");
4679 return L2CAP_TXSEQ_EXPECTED;
4680 }
4681 }
4682
4683 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
4684 __seq_offset(chan, chan->expected_tx_seq,
4685 chan->last_acked_seq)){
4686 BT_DBG("Duplicate - expected_tx_seq later than txseq");
4687 return L2CAP_TXSEQ_DUPLICATE;
4688 }
4689
4690 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
4691 /* A source of invalid packets is a "double poll" condition,
4692 * where delays cause us to send multiple poll packets. If
4693 * the remote stack receives and processes both polls,
4694 * sequence numbers can wrap around in such a way that a
4695 * resent frame has a sequence number that looks like new data
4696 * with a sequence gap. This would trigger an erroneous SREJ
4697 * request.
4698 *
4699 * Fortunately, this is impossible with a tx window that's
4700 * less than half of the maximum sequence number, which allows
4701 * invalid frames to be safely ignored.
4702 *
4703 * With tx window sizes greater than half of the tx window
4704 * maximum, the frame is invalid and cannot be ignored. This
4705 * causes a disconnect.
4706 */
4707
4708 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4709 BT_DBG("Invalid/Ignore - txseq outside tx window");
4710 return L2CAP_TXSEQ_INVALID_IGNORE;
4711 } else {
4712 BT_DBG("Invalid - txseq outside tx window");
4713 return L2CAP_TXSEQ_INVALID;
4714 }
4715 } else {
4716 BT_DBG("Unexpected - txseq indicates missing frames");
4717 return L2CAP_TXSEQ_UNEXPECTED;
4718 }
4719}
4720
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004721static int l2cap_rx_state_recv(struct l2cap_chan *chan,
4722 struct l2cap_ctrl *control,
4723 struct sk_buff *skb, u8 event)
4724{
4725 int err = 0;
4726 bool skb_in_use = 0;
4727
4728 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4729 event);
4730
4731 switch (event) {
4732 case L2CAP_EV_RECV_IFRAME:
4733 switch (l2cap_classify_txseq(chan, control->txseq)) {
4734 case L2CAP_TXSEQ_EXPECTED:
4735 l2cap_pass_to_tx(chan, control);
4736
4737 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4738 BT_DBG("Busy, discarding expected seq %d",
4739 control->txseq);
4740 break;
4741 }
4742
4743 chan->expected_tx_seq = __next_seq(chan,
4744 control->txseq);
4745
4746 chan->buffer_seq = chan->expected_tx_seq;
4747 skb_in_use = 1;
4748
4749 err = l2cap_reassemble_sdu(chan, skb, control);
4750 if (err)
4751 break;
4752
4753 if (control->final) {
4754 if (!test_and_clear_bit(CONN_REJ_ACT,
4755 &chan->conn_state)) {
4756 control->final = 0;
4757 l2cap_retransmit_all(chan, control);
4758 l2cap_ertm_send(chan);
4759 }
4760 }
4761
4762 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
4763 l2cap_send_ack(chan);
4764 break;
4765 case L2CAP_TXSEQ_UNEXPECTED:
4766 l2cap_pass_to_tx(chan, control);
4767
4768 /* Can't issue SREJ frames in the local busy state.
4769 * Drop this frame, it will be seen as missing
4770 * when local busy is exited.
4771 */
4772 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4773 BT_DBG("Busy, discarding unexpected seq %d",
4774 control->txseq);
4775 break;
4776 }
4777
4778 /* There was a gap in the sequence, so an SREJ
4779 * must be sent for each missing frame. The
4780 * current frame is stored for later use.
4781 */
4782 skb_queue_tail(&chan->srej_q, skb);
4783 skb_in_use = 1;
4784 BT_DBG("Queued %p (queue len %d)", skb,
4785 skb_queue_len(&chan->srej_q));
4786
4787 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
4788 l2cap_seq_list_clear(&chan->srej_list);
4789 l2cap_send_srej(chan, control->txseq);
4790
4791 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
4792 break;
4793 case L2CAP_TXSEQ_DUPLICATE:
4794 l2cap_pass_to_tx(chan, control);
4795 break;
4796 case L2CAP_TXSEQ_INVALID_IGNORE:
4797 break;
4798 case L2CAP_TXSEQ_INVALID:
4799 default:
4800 l2cap_send_disconn_req(chan->conn, chan,
4801 ECONNRESET);
4802 break;
4803 }
4804 break;
4805 case L2CAP_EV_RECV_RR:
4806 l2cap_pass_to_tx(chan, control);
4807 if (control->final) {
4808 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4809
4810 if (!test_and_clear_bit(CONN_REJ_ACT,
4811 &chan->conn_state)) {
4812 control->final = 0;
4813 l2cap_retransmit_all(chan, control);
4814 }
4815
4816 l2cap_ertm_send(chan);
4817 } else if (control->poll) {
4818 l2cap_send_i_or_rr_or_rnr(chan);
4819 } else {
4820 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4821 &chan->conn_state) &&
4822 chan->unacked_frames)
4823 __set_retrans_timer(chan);
4824
4825 l2cap_ertm_send(chan);
4826 }
4827 break;
4828 case L2CAP_EV_RECV_RNR:
4829 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4830 l2cap_pass_to_tx(chan, control);
4831 if (control && control->poll) {
4832 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4833 l2cap_send_rr_or_rnr(chan, 0);
4834 }
4835 __clear_retrans_timer(chan);
4836 l2cap_seq_list_clear(&chan->retrans_list);
4837 break;
4838 case L2CAP_EV_RECV_REJ:
4839 l2cap_handle_rej(chan, control);
4840 break;
4841 case L2CAP_EV_RECV_SREJ:
4842 l2cap_handle_srej(chan, control);
4843 break;
4844 default:
4845 break;
4846 }
4847
4848 if (skb && !skb_in_use) {
4849 BT_DBG("Freeing %p", skb);
4850 kfree_skb(skb);
4851 }
4852
4853 return err;
4854}
4855
4856static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
4857 struct l2cap_ctrl *control,
4858 struct sk_buff *skb, u8 event)
4859{
4860 int err = 0;
4861 u16 txseq = control->txseq;
4862 bool skb_in_use = 0;
4863
4864 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4865 event);
4866
4867 switch (event) {
4868 case L2CAP_EV_RECV_IFRAME:
4869 switch (l2cap_classify_txseq(chan, txseq)) {
4870 case L2CAP_TXSEQ_EXPECTED:
4871 /* Keep frame for reassembly later */
4872 l2cap_pass_to_tx(chan, control);
4873 skb_queue_tail(&chan->srej_q, skb);
4874 skb_in_use = 1;
4875 BT_DBG("Queued %p (queue len %d)", skb,
4876 skb_queue_len(&chan->srej_q));
4877
4878 chan->expected_tx_seq = __next_seq(chan, txseq);
4879 break;
4880 case L2CAP_TXSEQ_EXPECTED_SREJ:
4881 l2cap_seq_list_pop(&chan->srej_list);
4882
4883 l2cap_pass_to_tx(chan, control);
4884 skb_queue_tail(&chan->srej_q, skb);
4885 skb_in_use = 1;
4886 BT_DBG("Queued %p (queue len %d)", skb,
4887 skb_queue_len(&chan->srej_q));
4888
4889 err = l2cap_rx_queued_iframes(chan);
4890 if (err)
4891 break;
4892
4893 break;
4894 case L2CAP_TXSEQ_UNEXPECTED:
4895 /* Got a frame that can't be reassembled yet.
4896 * Save it for later, and send SREJs to cover
4897 * the missing frames.
4898 */
4899 skb_queue_tail(&chan->srej_q, skb);
4900 skb_in_use = 1;
4901 BT_DBG("Queued %p (queue len %d)", skb,
4902 skb_queue_len(&chan->srej_q));
4903
4904 l2cap_pass_to_tx(chan, control);
4905 l2cap_send_srej(chan, control->txseq);
4906 break;
4907 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
4908 /* This frame was requested with an SREJ, but
4909 * some expected retransmitted frames are
4910 * missing. Request retransmission of missing
4911 * SREJ'd frames.
4912 */
4913 skb_queue_tail(&chan->srej_q, skb);
4914 skb_in_use = 1;
4915 BT_DBG("Queued %p (queue len %d)", skb,
4916 skb_queue_len(&chan->srej_q));
4917
4918 l2cap_pass_to_tx(chan, control);
4919 l2cap_send_srej_list(chan, control->txseq);
4920 break;
4921 case L2CAP_TXSEQ_DUPLICATE_SREJ:
4922 /* We've already queued this frame. Drop this copy. */
4923 l2cap_pass_to_tx(chan, control);
4924 break;
4925 case L2CAP_TXSEQ_DUPLICATE:
4926 /* Expecting a later sequence number, so this frame
4927 * was already received. Ignore it completely.
4928 */
4929 break;
4930 case L2CAP_TXSEQ_INVALID_IGNORE:
4931 break;
4932 case L2CAP_TXSEQ_INVALID:
4933 default:
4934 l2cap_send_disconn_req(chan->conn, chan,
4935 ECONNRESET);
4936 break;
4937 }
4938 break;
4939 case L2CAP_EV_RECV_RR:
4940 l2cap_pass_to_tx(chan, control);
4941 if (control->final) {
4942 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4943
4944 if (!test_and_clear_bit(CONN_REJ_ACT,
4945 &chan->conn_state)) {
4946 control->final = 0;
4947 l2cap_retransmit_all(chan, control);
4948 }
4949
4950 l2cap_ertm_send(chan);
4951 } else if (control->poll) {
4952 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4953 &chan->conn_state) &&
4954 chan->unacked_frames) {
4955 __set_retrans_timer(chan);
4956 }
4957
4958 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4959 l2cap_send_srej_tail(chan);
4960 } else {
4961 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4962 &chan->conn_state) &&
4963 chan->unacked_frames)
4964 __set_retrans_timer(chan);
4965
4966 l2cap_send_ack(chan);
4967 }
4968 break;
4969 case L2CAP_EV_RECV_RNR:
4970 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4971 l2cap_pass_to_tx(chan, control);
4972 if (control->poll) {
4973 l2cap_send_srej_tail(chan);
4974 } else {
4975 struct l2cap_ctrl rr_control;
4976 memset(&rr_control, 0, sizeof(rr_control));
4977 rr_control.sframe = 1;
4978 rr_control.super = L2CAP_SUPER_RR;
4979 rr_control.reqseq = chan->buffer_seq;
4980 l2cap_send_sframe(chan, &rr_control);
4981 }
4982
4983 break;
4984 case L2CAP_EV_RECV_REJ:
4985 l2cap_handle_rej(chan, control);
4986 break;
4987 case L2CAP_EV_RECV_SREJ:
4988 l2cap_handle_srej(chan, control);
4989 break;
4990 }
4991
4992 if (skb && !skb_in_use) {
4993 BT_DBG("Freeing %p", skb);
4994 kfree_skb(skb);
4995 }
4996
4997 return err;
4998}
4999
5000static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
5001{
5002 /* Make sure reqseq is for a packet that has been sent but not acked */
5003 u16 unacked;
5004
5005 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
5006 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
5007}
5008
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005009static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5010 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005011{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005012 int err = 0;
5013
5014 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
5015 control, skb, event, chan->rx_state);
5016
5017 if (__valid_reqseq(chan, control->reqseq)) {
5018 switch (chan->rx_state) {
5019 case L2CAP_RX_STATE_RECV:
5020 err = l2cap_rx_state_recv(chan, control, skb, event);
5021 break;
5022 case L2CAP_RX_STATE_SREJ_SENT:
5023 err = l2cap_rx_state_srej_sent(chan, control, skb,
5024 event);
5025 break;
5026 default:
5027 /* shut it down */
5028 break;
5029 }
5030 } else {
5031 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
5032 control->reqseq, chan->next_tx_seq,
5033 chan->expected_ack_seq);
5034 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
5035 }
5036
5037 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005038}
5039
5040static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5041 struct sk_buff *skb)
5042{
Mat Martineau4b51dae92012-05-17 20:53:37 -07005043 int err = 0;
5044
5045 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
5046 chan->rx_state);
5047
5048 if (l2cap_classify_txseq(chan, control->txseq) ==
5049 L2CAP_TXSEQ_EXPECTED) {
5050 l2cap_pass_to_tx(chan, control);
5051
5052 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
5053 __next_seq(chan, chan->buffer_seq));
5054
5055 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5056
5057 l2cap_reassemble_sdu(chan, skb, control);
5058 } else {
5059 if (chan->sdu) {
5060 kfree_skb(chan->sdu);
5061 chan->sdu = NULL;
5062 }
5063 chan->sdu_last_frag = NULL;
5064 chan->sdu_len = 0;
5065
5066 if (skb) {
5067 BT_DBG("Freeing %p", skb);
5068 kfree_skb(skb);
5069 }
5070 }
5071
5072 chan->last_acked_seq = control->txseq;
5073 chan->expected_tx_seq = __next_seq(chan, control->txseq);
5074
5075 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005076}
5077
5078static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
5079{
5080 struct l2cap_ctrl *control = &bt_cb(skb)->control;
5081 u16 len;
5082 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005083
Mat Martineaub76bbd62012-04-11 10:48:43 -07005084 __unpack_control(chan, skb);
5085
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005086 len = skb->len;
5087
5088 /*
5089 * We can just drop the corrupted I-frame here.
5090 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005091 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005092 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005093 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005094 goto drop;
5095
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005096 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005097 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005098
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005099 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005100 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005101
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005102 if (len > chan->mps) {
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005103 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005104 goto drop;
5105 }
5106
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005107 if (!control->sframe) {
5108 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005109
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005110 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
5111 control->sar, control->reqseq, control->final,
5112 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03005113
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005114 /* Validate F-bit - F=0 always valid, F=1 only
5115 * valid in TX WAIT_F
5116 */
5117 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005118 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005119
5120 if (chan->mode != L2CAP_MODE_STREAMING) {
5121 event = L2CAP_EV_RECV_IFRAME;
5122 err = l2cap_rx(chan, control, skb, event);
5123 } else {
5124 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005125 }
5126
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005127 if (err)
5128 l2cap_send_disconn_req(chan->conn, chan,
5129 ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005130 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005131 const u8 rx_func_to_event[4] = {
5132 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
5133 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
5134 };
5135
5136 /* Only I-frames are expected in streaming mode */
5137 if (chan->mode == L2CAP_MODE_STREAMING)
5138 goto drop;
5139
5140 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
5141 control->reqseq, control->final, control->poll,
5142 control->super);
5143
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005144 if (len != 0) {
5145 BT_ERR("%d", len);
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005146 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005147 goto drop;
5148 }
5149
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005150 /* Validate F and P bits */
5151 if (control->final && (control->poll ||
5152 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
5153 goto drop;
5154
5155 event = rx_func_to_event[control->super];
5156 if (l2cap_rx(chan, control, skb, event))
5157 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005158 }
5159
5160 return 0;
5161
5162drop:
5163 kfree_skb(skb);
5164 return 0;
5165}
5166
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005167static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
5168 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005169{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005170 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005171
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03005172 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005173 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005174 if (cid == L2CAP_CID_A2MP) {
5175 chan = a2mp_channel_create(conn, skb);
5176 if (!chan) {
5177 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005178 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005179 }
5180
5181 l2cap_chan_lock(chan);
5182 } else {
5183 BT_DBG("unknown cid 0x%4.4x", cid);
5184 /* Drop packet and return */
5185 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005186 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005187 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005188 }
5189
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03005190 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005191
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005192 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005193 goto drop;
5194
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005195 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005196 case L2CAP_MODE_BASIC:
5197 /* If socket recv buffers overflows we drop data here
5198 * which is *bad* because L2CAP has to be reliable.
5199 * But we don't have any other choice. L2CAP doesn't
5200 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005201
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005202 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005203 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005204
Gustavo Padovan80b98022012-05-27 22:27:51 -03005205 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005206 goto done;
5207 break;
5208
5209 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005210 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005211 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005212 goto done;
5213
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005214 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005215 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005216 break;
5217 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005218
5219drop:
5220 kfree_skb(skb);
5221
5222done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005223 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005224}
5225
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03005226static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
5227 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005228{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005229 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005230
Ido Yarivc2287682012-04-20 15:46:07 -03005231 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005232 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005233 goto drop;
5234
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005235 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005236
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005237 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005238 goto drop;
5239
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005240 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005241 goto drop;
5242
Gustavo Padovan80b98022012-05-27 22:27:51 -03005243 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03005244 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005245
5246drop:
5247 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005248}
5249
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03005250static void l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
5251 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005252{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005253 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005254
Ido Yarivc2287682012-04-20 15:46:07 -03005255 chan = l2cap_global_chan_by_scid(0, cid, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005256 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005257 goto drop;
5258
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005259 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005260
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005261 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005262 goto drop;
5263
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005264 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005265 goto drop;
5266
Gustavo Padovan80b98022012-05-27 22:27:51 -03005267 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03005268 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005269
5270drop:
5271 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005272}
5273
Linus Torvalds1da177e2005-04-16 15:20:36 -07005274static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
5275{
5276 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07005277 u16 cid, len;
5278 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005279
5280 skb_pull(skb, L2CAP_HDR_SIZE);
5281 cid = __le16_to_cpu(lh->cid);
5282 len = __le16_to_cpu(lh->len);
5283
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005284 if (len != skb->len) {
5285 kfree_skb(skb);
5286 return;
5287 }
5288
Linus Torvalds1da177e2005-04-16 15:20:36 -07005289 BT_DBG("len %d, cid 0x%4.4x", len, cid);
5290
5291 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005292 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005293 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005294 l2cap_sig_channel(conn, skb);
5295 break;
5296
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005297 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02005298 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03005299 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005300 l2cap_conless_channel(conn, psm, skb);
5301 break;
5302
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005303 case L2CAP_CID_LE_DATA:
5304 l2cap_att_channel(conn, cid, skb);
5305 break;
5306
Anderson Brigliab501d6a2011-06-07 18:46:31 -03005307 case L2CAP_CID_SMP:
5308 if (smp_sig_channel(conn, skb))
5309 l2cap_conn_del(conn->hcon, EACCES);
5310 break;
5311
Linus Torvalds1da177e2005-04-16 15:20:36 -07005312 default:
5313 l2cap_data_channel(conn, cid, skb);
5314 break;
5315 }
5316}
5317
5318/* ---- L2CAP interface with lower layer (HCI) ---- */
5319
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005320int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005321{
5322 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005323 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005324
Linus Torvalds1da177e2005-04-16 15:20:36 -07005325 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
5326
5327 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005328 read_lock(&chan_list_lock);
5329 list_for_each_entry(c, &chan_list, global_l) {
5330 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005331
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005332 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005333 continue;
5334
5335 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005336 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005337 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005338 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005339 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005340 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
5341 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005342 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005343 lm2 |= HCI_LM_MASTER;
5344 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005345 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005346 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005347
5348 return exact ? lm1 : lm2;
5349}
5350
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03005351void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005352{
Marcel Holtmann01394182006-07-03 10:02:46 +02005353 struct l2cap_conn *conn;
5354
Linus Torvalds1da177e2005-04-16 15:20:36 -07005355 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
5356
Linus Torvalds1da177e2005-04-16 15:20:36 -07005357 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005358 conn = l2cap_conn_add(hcon, status);
5359 if (conn)
5360 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02005361 } else
Joe Perchese1750722011-06-29 18:18:29 -07005362 l2cap_conn_del(hcon, bt_to_errno(status));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005363
Linus Torvalds1da177e2005-04-16 15:20:36 -07005364}
5365
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005366int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01005367{
5368 struct l2cap_conn *conn = hcon->l2cap_data;
5369
5370 BT_DBG("hcon %p", hcon);
5371
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005372 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02005373 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01005374 return conn->disc_reason;
5375}
5376
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03005377void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005378{
5379 BT_DBG("hcon %p reason %d", hcon, reason);
5380
Joe Perchese1750722011-06-29 18:18:29 -07005381 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005382}
5383
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005384static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005385{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03005386 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01005387 return;
5388
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005389 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005390 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005391 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005392 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03005393 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005394 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005395 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03005396 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005397 }
5398}
5399
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005400int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005401{
Marcel Holtmann40be4922008-07-14 20:13:50 +02005402 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005403 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005404
Marcel Holtmann01394182006-07-03 10:02:46 +02005405 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005406 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02005407
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03005408 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005409
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005410 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05305411 if (!status && encrypt)
5412 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02005413 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005414 }
5415
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005416 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005417
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005418 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005419 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005420
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03005421 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
5422 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005423
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03005424 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
5425 l2cap_chan_unlock(chan);
5426 continue;
5427 }
5428
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005429 if (chan->scid == L2CAP_CID_LE_DATA) {
5430 if (!status && encrypt) {
5431 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02005432 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005433 }
5434
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005435 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005436 continue;
5437 }
5438
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03005439 if (test_bit(CONF_CONNECT_PEND, &chan->conf_state)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005440 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01005441 continue;
5442 }
5443
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005444 if (!status && (chan->state == BT_CONNECTED ||
5445 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03005446 struct sock *sk = chan->sk;
5447
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005448 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03005449 sk->sk_state_change(sk);
5450
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005451 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005452 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02005453 continue;
5454 }
5455
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005456 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005457 if (!status) {
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02005458 l2cap_send_conn_req(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005459 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005460 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005461 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005462 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005463 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005464 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005465 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005466
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005467 lock_sock(sk);
5468
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005469 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005470 if (test_bit(BT_SK_DEFER_SETUP,
5471 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005472 struct sock *parent = bt_sk(sk)->parent;
5473 res = L2CAP_CR_PEND;
5474 stat = L2CAP_CS_AUTHOR_PEND;
Ilia Kolomisnky05e9a2f2011-07-15 18:30:21 +00005475 if (parent)
5476 parent->sk_data_ready(parent, 0);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005477 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005478 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005479 res = L2CAP_CR_SUCCESS;
5480 stat = L2CAP_CS_NO_INFO;
5481 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005482 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005483 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005484 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005485 res = L2CAP_CR_SEC_BLOCK;
5486 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005487 }
5488
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005489 release_sock(sk);
5490
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03005491 rsp.scid = cpu_to_le16(chan->dcid);
5492 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005493 rsp.result = cpu_to_le16(res);
5494 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03005495 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
5496 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07005497
5498 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
5499 res == L2CAP_CR_SUCCESS) {
5500 char buf[128];
5501 set_bit(CONF_REQ_SENT, &chan->conf_state);
5502 l2cap_send_cmd(conn, l2cap_get_ident(conn),
5503 L2CAP_CONF_REQ,
5504 l2cap_build_conf_req(chan, buf),
5505 buf);
5506 chan->num_conf_req++;
5507 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005508 }
5509
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005510 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005511 }
5512
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005513 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005514
Linus Torvalds1da177e2005-04-16 15:20:36 -07005515 return 0;
5516}
5517
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005518int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005519{
5520 struct l2cap_conn *conn = hcon->l2cap_data;
5521
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02005522 if (!conn)
5523 conn = l2cap_conn_add(hcon, 0);
5524
5525 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005526 goto drop;
5527
5528 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
5529
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +02005530 if (!(flags & ACL_CONT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005531 struct l2cap_hdr *hdr;
5532 int len;
5533
5534 if (conn->rx_len) {
5535 BT_ERR("Unexpected start frame (len %d)", skb->len);
5536 kfree_skb(conn->rx_skb);
5537 conn->rx_skb = NULL;
5538 conn->rx_len = 0;
5539 l2cap_conn_unreliable(conn, ECOMM);
5540 }
5541
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03005542 /* Start fragment always begin with Basic L2CAP header */
5543 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005544 BT_ERR("Frame is too short (len %d)", skb->len);
5545 l2cap_conn_unreliable(conn, ECOMM);
5546 goto drop;
5547 }
5548
5549 hdr = (struct l2cap_hdr *) skb->data;
5550 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
5551
5552 if (len == skb->len) {
5553 /* Complete frame received */
5554 l2cap_recv_frame(conn, skb);
5555 return 0;
5556 }
5557
5558 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
5559
5560 if (skb->len > len) {
5561 BT_ERR("Frame is too long (len %d, expected len %d)",
5562 skb->len, len);
5563 l2cap_conn_unreliable(conn, ECOMM);
5564 goto drop;
5565 }
5566
5567 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03005568 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
5569 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005570 goto drop;
5571
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005572 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01005573 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005574 conn->rx_len = len - skb->len;
5575 } else {
5576 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
5577
5578 if (!conn->rx_len) {
5579 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
5580 l2cap_conn_unreliable(conn, ECOMM);
5581 goto drop;
5582 }
5583
5584 if (skb->len > conn->rx_len) {
5585 BT_ERR("Fragment is too long (len %d, expected %d)",
5586 skb->len, conn->rx_len);
5587 kfree_skb(conn->rx_skb);
5588 conn->rx_skb = NULL;
5589 conn->rx_len = 0;
5590 l2cap_conn_unreliable(conn, ECOMM);
5591 goto drop;
5592 }
5593
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005594 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01005595 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005596 conn->rx_len -= skb->len;
5597
5598 if (!conn->rx_len) {
5599 /* Complete frame received */
5600 l2cap_recv_frame(conn, conn->rx_skb);
5601 conn->rx_skb = NULL;
5602 }
5603 }
5604
5605drop:
5606 kfree_skb(skb);
5607 return 0;
5608}
5609
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005610static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005611{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005612 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005613
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005614 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005615
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005616 list_for_each_entry(c, &chan_list, global_l) {
5617 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005618
Gustavo F. Padovan903d3432011-02-10 14:16:06 -02005619 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 +01005620 batostr(&bt_sk(sk)->src),
5621 batostr(&bt_sk(sk)->dst),
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005622 c->state, __le16_to_cpu(c->psm),
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005623 c->scid, c->dcid, c->imtu, c->omtu,
5624 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02005625 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005626
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005627 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005628
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005629 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005630}
5631
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005632static int l2cap_debugfs_open(struct inode *inode, struct file *file)
5633{
5634 return single_open(file, l2cap_debugfs_show, inode->i_private);
5635}
5636
5637static const struct file_operations l2cap_debugfs_fops = {
5638 .open = l2cap_debugfs_open,
5639 .read = seq_read,
5640 .llseek = seq_lseek,
5641 .release = single_release,
5642};
5643
5644static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005645
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005646int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005647{
5648 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005649
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005650 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005651 if (err < 0)
5652 return err;
5653
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005654 if (bt_debugfs) {
5655 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
5656 bt_debugfs, NULL, &l2cap_debugfs_fops);
5657 if (!l2cap_debugfs)
5658 BT_ERR("Failed to create L2CAP debug file");
5659 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005660
Linus Torvalds1da177e2005-04-16 15:20:36 -07005661 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005662}
5663
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005664void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005665{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005666 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005667 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005668}
5669
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03005670module_param(disable_ertm, bool, 0644);
5671MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");