blob: a91239dcda417f5a862346c981bb941aba44d086 [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
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530409 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300410
Mat Martineau28270112012-05-17 21:14:09 -0700411 /* This flag is cleared in l2cap_chan_ready() */
412 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
413
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300414 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100415
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300416 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200417}
418
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530419static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300420{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530421 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
422
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530423 BT_DBG("chan %p", chan);
424
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200425 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300426 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200427 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300428
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530429 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300430}
431
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530432void l2cap_chan_hold(struct l2cap_chan *c)
433{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530434 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530435
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530436 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530437}
438
439void l2cap_chan_put(struct l2cap_chan *c)
440{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530441 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530442
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530443 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530444}
445
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300446void l2cap_chan_set_defaults(struct l2cap_chan *chan)
447{
448 chan->fcs = L2CAP_FCS_CRC16;
449 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
450 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
451 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700452 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300453 chan->sec_level = BT_SECURITY_LOW;
454
455 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
456}
457
Andrei Emeltchenko14a28492012-03-23 16:31:49 +0200458static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200459{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300460 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200461 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200462
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200463 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100464
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300465 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200466
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200467 switch (chan->chan_type) {
468 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300469 if (conn->hcon->type == LE_LINK) {
470 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300471 chan->omtu = L2CAP_DEFAULT_MTU;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300472 chan->scid = L2CAP_CID_LE_DATA;
473 chan->dcid = L2CAP_CID_LE_DATA;
Ville Tervob62f3282011-02-10 22:38:50 -0300474 } else {
475 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300476 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300477 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300478 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200479 break;
480
481 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200482 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300483 chan->scid = L2CAP_CID_CONN_LESS;
484 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300485 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200486 break;
487
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300488 case L2CAP_CHAN_CONN_FIX_A2MP:
489 chan->scid = L2CAP_CID_A2MP;
490 chan->dcid = L2CAP_CID_A2MP;
491 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
492 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
493 break;
494
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200495 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200496 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300497 chan->scid = L2CAP_CID_SIGNALING;
498 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300499 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200500 }
501
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300502 chan->local_id = L2CAP_BESTEFFORT_ID;
503 chan->local_stype = L2CAP_SERV_BESTEFFORT;
504 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
505 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
506 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
507 chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO;
508
Ulisses Furquim371fd832011-12-21 20:02:36 -0200509 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300510
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200511 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200512}
513
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300514void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200515{
516 mutex_lock(&conn->chan_lock);
517 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200518 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200519}
520
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300521void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200522{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300523 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200524
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300525 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200526
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300527 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200528
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900529 if (conn) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300530 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200531 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200532
Ulisses Furquim371fd832011-12-21 20:02:36 -0200533 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300534
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300535 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300536
537 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
538 hci_conn_put(conn->hcon);
Marcel Holtmann01394182006-07-03 10:02:46 +0200539 }
540
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300541 if (chan->ops->teardown)
542 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200543
Mat Martineau28270112012-05-17 21:14:09 -0700544 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300545 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300546
Gustavo Padovanee556f62012-05-18 20:22:38 -0300547 switch(chan->mode) {
548 case L2CAP_MODE_BASIC:
549 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300550
Gustavo Padovanee556f62012-05-18 20:22:38 -0300551 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300552 __clear_retrans_timer(chan);
553 __clear_monitor_timer(chan);
554 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300555
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300556 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300557
Mat Martineau3c588192012-04-11 10:48:42 -0700558 l2cap_seq_list_free(&chan->srej_list);
559 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300560
561 /* fall through */
562
563 case L2CAP_MODE_STREAMING:
564 skb_queue_purge(&chan->tx_q);
565 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300566 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300567
568 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200569}
570
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300571void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300572{
573 struct l2cap_conn *conn = chan->conn;
574 struct sock *sk = chan->sk;
575
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200576 BT_DBG("chan %p state %s sk %p", chan,
577 state_to_string(chan->state), sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300578
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300579 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300580 case BT_LISTEN:
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300581 if (chan->ops->teardown)
582 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300583 break;
584
585 case BT_CONNECTED:
586 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300587 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300588 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300589 __set_chan_timer(chan, sk->sk_sndtimeo);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300590 l2cap_send_disconn_req(conn, chan, reason);
591 } else
592 l2cap_chan_del(chan, reason);
593 break;
594
595 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300596 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300597 conn->hcon->type == ACL_LINK) {
598 struct l2cap_conn_rsp rsp;
599 __u16 result;
600
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300601 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300602 result = L2CAP_CR_SEC_BLOCK;
603 else
604 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300605 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300606
607 rsp.scid = cpu_to_le16(chan->dcid);
608 rsp.dcid = cpu_to_le16(chan->scid);
609 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300610 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300611 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
612 sizeof(rsp), &rsp);
613 }
614
615 l2cap_chan_del(chan, reason);
616 break;
617
618 case BT_CONNECT:
619 case BT_DISCONN:
620 l2cap_chan_del(chan, reason);
621 break;
622
623 default:
Andrei Emeltchenkoc0df7f62012-05-27 22:27:52 -0300624 if (chan->ops->teardown)
625 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300626 break;
627 }
628}
629
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300630static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530631{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300632 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300633 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530634 case BT_SECURITY_HIGH:
635 return HCI_AT_DEDICATED_BONDING_MITM;
636 case BT_SECURITY_MEDIUM:
637 return HCI_AT_DEDICATED_BONDING;
638 default:
639 return HCI_AT_NO_BONDING;
640 }
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +0300641 } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300642 if (chan->sec_level == BT_SECURITY_LOW)
643 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530644
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300645 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530646 return HCI_AT_NO_BONDING_MITM;
647 else
648 return HCI_AT_NO_BONDING;
649 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300650 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530651 case BT_SECURITY_HIGH:
652 return HCI_AT_GENERAL_BONDING_MITM;
653 case BT_SECURITY_MEDIUM:
654 return HCI_AT_GENERAL_BONDING;
655 default:
656 return HCI_AT_NO_BONDING;
657 }
658 }
659}
660
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200661/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200662int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200663{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300664 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100665 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200666
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300667 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100668
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300669 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200670}
671
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200672static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200673{
674 u8 id;
675
676 /* Get next available identificator.
677 * 1 - 128 are used by kernel.
678 * 129 - 199 are reserved.
679 * 200 - 254 are used by utilities like l2ping, etc.
680 */
681
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200682 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200683
684 if (++conn->tx_ident > 128)
685 conn->tx_ident = 1;
686
687 id = conn->tx_ident;
688
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200689 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200690
691 return id;
692}
693
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300694static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200695{
696 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200697 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200698
699 BT_DBG("code 0x%2.2x", code);
700
701 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300702 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200703
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200704 if (lmp_no_flush_capable(conn->hcon->hdev))
705 flags = ACL_START_NO_FLUSH;
706 else
707 flags = ACL_START;
708
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700709 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200710 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700711
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200712 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200713}
714
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200715static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
716{
717 struct hci_conn *hcon = chan->conn->hcon;
718 u16 flags;
719
720 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
721 skb->priority);
722
723 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
724 lmp_no_flush_capable(hcon->hdev))
725 flags = ACL_START_NO_FLUSH;
726 else
727 flags = ACL_START;
728
729 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
730 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731}
732
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700733static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
734{
735 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
736 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
737
738 if (enh & L2CAP_CTRL_FRAME_TYPE) {
739 /* S-Frame */
740 control->sframe = 1;
741 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
742 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
743
744 control->sar = 0;
745 control->txseq = 0;
746 } else {
747 /* I-Frame */
748 control->sframe = 0;
749 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
750 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
751
752 control->poll = 0;
753 control->super = 0;
754 }
755}
756
757static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
758{
759 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
760 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
761
762 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
763 /* S-Frame */
764 control->sframe = 1;
765 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
766 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
767
768 control->sar = 0;
769 control->txseq = 0;
770 } else {
771 /* I-Frame */
772 control->sframe = 0;
773 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
774 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
775
776 control->poll = 0;
777 control->super = 0;
778 }
779}
780
781static inline void __unpack_control(struct l2cap_chan *chan,
782 struct sk_buff *skb)
783{
784 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
785 __unpack_extended_control(get_unaligned_le32(skb->data),
786 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700787 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700788 } else {
789 __unpack_enhanced_control(get_unaligned_le16(skb->data),
790 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700791 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700792 }
793}
794
795static u32 __pack_extended_control(struct l2cap_ctrl *control)
796{
797 u32 packed;
798
799 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
800 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
801
802 if (control->sframe) {
803 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
804 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
805 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
806 } else {
807 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
808 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
809 }
810
811 return packed;
812}
813
814static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
815{
816 u16 packed;
817
818 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
819 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
820
821 if (control->sframe) {
822 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
823 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
824 packed |= L2CAP_CTRL_FRAME_TYPE;
825 } else {
826 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
827 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
828 }
829
830 return packed;
831}
832
833static inline void __pack_control(struct l2cap_chan *chan,
834 struct l2cap_ctrl *control,
835 struct sk_buff *skb)
836{
837 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
838 put_unaligned_le32(__pack_extended_control(control),
839 skb->data + L2CAP_HDR_SIZE);
840 } else {
841 put_unaligned_le16(__pack_enhanced_control(control),
842 skb->data + L2CAP_HDR_SIZE);
843 }
844}
845
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300846static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
847{
848 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
849 return L2CAP_EXT_HDR_SIZE;
850 else
851 return L2CAP_ENH_HDR_SIZE;
852}
853
Mat Martineaua67d7f62012-05-17 20:53:35 -0700854static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
855 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300856{
857 struct sk_buff *skb;
858 struct l2cap_hdr *lh;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300859 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300860
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300861 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300862 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300863
Mat Martineaua67d7f62012-05-17 20:53:35 -0700864 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300865
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300866 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700867 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300868
869 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300870 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300871 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300872
Mat Martineaua67d7f62012-05-17 20:53:35 -0700873 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
874 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
875 else
876 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300877
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300878 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700879 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300880 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300881 }
882
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200883 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700884 return skb;
885}
886
887static void l2cap_send_sframe(struct l2cap_chan *chan,
888 struct l2cap_ctrl *control)
889{
890 struct sk_buff *skb;
891 u32 control_field;
892
893 BT_DBG("chan %p, control %p", chan, control);
894
895 if (!control->sframe)
896 return;
897
898 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
899 !control->poll)
900 control->final = 1;
901
902 if (control->super == L2CAP_SUPER_RR)
903 clear_bit(CONN_RNR_SENT, &chan->conn_state);
904 else if (control->super == L2CAP_SUPER_RNR)
905 set_bit(CONN_RNR_SENT, &chan->conn_state);
906
907 if (control->super != L2CAP_SUPER_SREJ) {
908 chan->last_acked_seq = control->reqseq;
909 __clear_ack_timer(chan);
910 }
911
912 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
913 control->final, control->poll, control->super);
914
915 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
916 control_field = __pack_extended_control(control);
917 else
918 control_field = __pack_enhanced_control(control);
919
920 skb = l2cap_create_sframe_pdu(chan, control_field);
921 if (!IS_ERR(skb))
922 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300923}
924
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700925static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300926{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700927 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300928
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700929 BT_DBG("chan %p, poll %d", chan, poll);
930
931 memset(&control, 0, sizeof(control));
932 control.sframe = 1;
933 control.poll = poll;
934
935 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
936 control.super = L2CAP_SUPER_RNR;
937 else
938 control.super = L2CAP_SUPER_RR;
939
940 control.reqseq = chan->buffer_seq;
941 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300942}
943
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300944static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300945{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -0300946 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300947}
948
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +0200949static void l2cap_send_conn_req(struct l2cap_chan *chan)
950{
951 struct l2cap_conn *conn = chan->conn;
952 struct l2cap_conn_req req;
953
954 req.scid = cpu_to_le16(chan->scid);
955 req.psm = chan->psm;
956
957 chan->ident = l2cap_get_ident(conn);
958
959 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
960
961 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
962}
963
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300964static void l2cap_chan_ready(struct l2cap_chan *chan)
965{
Mat Martineau28270112012-05-17 21:14:09 -0700966 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300967 chan->conf_state = 0;
968 __clear_chan_timer(chan);
969
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -0300970 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300971
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +0300972 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300973}
974
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -0300975static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200976{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300977 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200978
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300979 if (conn->hcon->type == LE_LINK) {
980 l2cap_chan_ready(chan);
981 return;
982 }
983
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200984 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +0100985 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
986 return;
987
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200988 if (l2cap_chan_check_security(chan) &&
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +0200989 __l2cap_no_conn_pending(chan))
990 l2cap_send_conn_req(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200991 } else {
992 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300993 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200994
995 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
996 conn->info_ident = l2cap_get_ident(conn);
997
Marcel Holtmannba13ccd2012-03-01 14:25:33 -0800998 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200999
1000 l2cap_send_cmd(conn, conn->info_ident,
1001 L2CAP_INFO_REQ, sizeof(req), &req);
1002 }
1003}
1004
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001005static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1006{
1007 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001008 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001009 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1010
1011 switch (mode) {
1012 case L2CAP_MODE_ERTM:
1013 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1014 case L2CAP_MODE_STREAMING:
1015 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1016 default:
1017 return 0x00;
1018 }
1019}
1020
Gustavo F. Padovan4519de92011-04-28 17:55:53 -03001021static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001022{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001023 struct sock *sk = chan->sk;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001024 struct l2cap_disconn_req req;
1025
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001026 if (!conn)
1027 return;
1028
Andrei Emeltchenkoaad3d0e2012-09-06 15:05:42 +03001029 if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001030 __clear_retrans_timer(chan);
1031 __clear_monitor_timer(chan);
1032 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001033 }
1034
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001035 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1036 __l2cap_state_change(chan, BT_DISCONN);
1037 return;
1038 }
1039
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001040 req.dcid = cpu_to_le16(chan->dcid);
1041 req.scid = cpu_to_le16(chan->scid);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001042 l2cap_send_cmd(conn, l2cap_get_ident(conn),
1043 L2CAP_DISCONN_REQ, sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001044
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001045 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001046 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001047 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001048 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001049}
1050
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001052static void l2cap_conn_start(struct l2cap_conn *conn)
1053{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001054 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001055
1056 BT_DBG("conn %p", conn);
1057
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001058 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001059
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001060 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001061 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001062
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001063 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001064
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001065 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001066 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001067 continue;
1068 }
1069
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001070 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001071 if (!l2cap_chan_check_security(chan) ||
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001072 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001073 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001074 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001075 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001076
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001077 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
1078 && test_bit(CONF_STATE2_DEVICE,
1079 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001080 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001081 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001082 continue;
1083 }
1084
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001085 l2cap_send_conn_req(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001086
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001087 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001088 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001089 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001090 rsp.scid = cpu_to_le16(chan->dcid);
1091 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001092
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001093 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001094 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001095 if (test_bit(BT_SK_DEFER_SETUP,
1096 &bt_sk(sk)->flags)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001097 struct sock *parent = bt_sk(sk)->parent;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001098 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1099 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Ilia Kolomisnky05e9a2f2011-07-15 18:30:21 +00001100 if (parent)
1101 parent->sk_data_ready(parent, 0);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001102
1103 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001104 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001105 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1106 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001107 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001108 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001109 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001110 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1111 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001112 }
1113
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001114 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
1115 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001116
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001117 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001118 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001119 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001120 continue;
1121 }
1122
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001123 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001124 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001125 l2cap_build_conf_req(chan, buf), buf);
1126 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001127 }
1128
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001129 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001130 }
1131
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001132 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001133}
1134
Ido Yarivc2287682012-04-20 15:46:07 -03001135/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001136 * Returns closest match, locked.
1137 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001138static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001139 bdaddr_t *src,
1140 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001141{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001142 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001143
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001144 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001145
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001146 list_for_each_entry(c, &chan_list, global_l) {
1147 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001148
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001149 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001150 continue;
1151
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001152 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001153 int src_match, dst_match;
1154 int src_any, dst_any;
1155
Ville Tervob62f3282011-02-10 22:38:50 -03001156 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001157 src_match = !bacmp(&bt_sk(sk)->src, src);
1158 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1159 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001160 read_unlock(&chan_list_lock);
1161 return c;
1162 }
Ville Tervob62f3282011-02-10 22:38:50 -03001163
1164 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001165 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1166 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1167 if ((src_match && dst_any) || (src_any && dst_match) ||
1168 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001169 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001170 }
1171 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001172
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001173 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001174
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001175 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001176}
1177
1178static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1179{
Gustavo F. Padovanc916fbe2011-04-04 16:00:55 -03001180 struct sock *parent, *sk;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001181 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001182
1183 BT_DBG("");
1184
1185 /* Check if we have socket listening on cid */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001186 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
Ido Yarivc2287682012-04-20 15:46:07 -03001187 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001188 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001189 return;
1190
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001191 parent = pchan->sk;
1192
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001193 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001194
Gustavo Padovan80b98022012-05-27 22:27:51 -03001195 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001196 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001197 goto clean;
1198
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001199 sk = chan->sk;
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001200
Ville Tervob62f3282011-02-10 22:38:50 -03001201 hci_conn_hold(conn->hcon);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001202 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
Ville Tervob62f3282011-02-10 22:38:50 -03001203
Ville Tervob62f3282011-02-10 22:38:50 -03001204 bacpy(&bt_sk(sk)->src, conn->src);
1205 bacpy(&bt_sk(sk)->dst, conn->dst);
1206
Gustavo F. Padovand1010242011-03-25 00:39:48 -03001207 bt_accept_enqueue(parent, sk);
1208
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001209 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001210
Gustavo Padovan6754e0d2012-05-25 09:30:56 -03001211 l2cap_chan_ready(chan);
Ville Tervob62f3282011-02-10 22:38:50 -03001212
Ville Tervob62f3282011-02-10 22:38:50 -03001213clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001214 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001215}
1216
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001217static void l2cap_conn_ready(struct l2cap_conn *conn)
1218{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001219 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001220 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001221
1222 BT_DBG("conn %p", conn);
1223
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001224 if (!hcon->out && hcon->type == LE_LINK)
Ville Tervob62f3282011-02-10 22:38:50 -03001225 l2cap_le_conn_ready(conn);
1226
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001227 if (hcon->out && hcon->type == LE_LINK)
1228 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001229
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001230 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001231
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001232 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001233
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001234 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001235
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001236 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1237 l2cap_chan_unlock(chan);
1238 continue;
1239 }
1240
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001241 if (hcon->type == LE_LINK) {
1242 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001243 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001244
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001245 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001246 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001247 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001248 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001249 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001250 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001251 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001252
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001253 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001254 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001255
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001256 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001257 }
1258
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001259 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001260}
1261
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001262/* Notify sockets that we cannot guaranty reliability anymore */
1263static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1264{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001265 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001266
1267 BT_DBG("conn %p", conn);
1268
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001269 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001270
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001271 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001272 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001273 __l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001274 }
1275
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001276 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001277}
1278
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001279static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001280{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001281 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001282 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001283
Marcel Holtmann984947d2009-02-06 23:35:19 +01001284 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001285 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001286
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001287 l2cap_conn_start(conn);
1288}
1289
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001290static void l2cap_conn_del(struct hci_conn *hcon, int err)
1291{
1292 struct l2cap_conn *conn = hcon->l2cap_data;
1293 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001294
1295 if (!conn)
1296 return;
1297
1298 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1299
1300 kfree_skb(conn->rx_skb);
1301
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001302 mutex_lock(&conn->chan_lock);
1303
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001304 /* Kill channels */
1305 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001306 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001307 l2cap_chan_lock(chan);
1308
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001309 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001310
1311 l2cap_chan_unlock(chan);
1312
Gustavo Padovan80b98022012-05-27 22:27:51 -03001313 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001314 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001315 }
1316
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001317 mutex_unlock(&conn->chan_lock);
1318
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001319 hci_chan_del(conn->hchan);
1320
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001321 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001322 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001323
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001324 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001325 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001326 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001327 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001328
1329 hcon->l2cap_data = NULL;
1330 kfree(conn);
1331}
1332
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001333static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001334{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001335 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
1336 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001337
Johan Hedbergd06cc412012-06-06 18:44:11 +08001338 BT_DBG("conn %p", conn);
1339
1340 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1341 smp_chan_destroy(conn);
1342 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1343 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001344}
1345
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
1347{
Marcel Holtmann01394182006-07-03 10:02:46 +02001348 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001349 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350
Marcel Holtmann01394182006-07-03 10:02:46 +02001351 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352 return conn;
1353
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001354 hchan = hci_chan_create(hcon);
1355 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001358 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
1359 if (!conn) {
1360 hci_chan_del(hchan);
1361 return NULL;
1362 }
1363
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364 hcon->l2cap_data = conn;
1365 conn->hcon = hcon;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001366 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001367
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001368 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001369
Ville Tervoacd7d372011-02-10 22:38:49 -03001370 if (hcon->hdev->le_mtu && hcon->type == LE_LINK)
1371 conn->mtu = hcon->hdev->le_mtu;
1372 else
1373 conn->mtu = hcon->hdev->acl_mtu;
1374
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375 conn->src = &hcon->hdev->bdaddr;
1376 conn->dst = &hcon->dst;
1377
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001378 conn->feat_mask = 0;
1379
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001381 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001382
1383 INIT_LIST_HEAD(&conn->chan_l);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001385 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001386 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001387 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001388 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001389
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001390 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001391
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392 return conn;
1393}
1394
Linus Torvalds1da177e2005-04-16 15:20:36 -07001395/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396
Ido Yarivc2287682012-04-20 15:46:07 -03001397/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001398 * Returns closest match.
1399 */
Ido Yarivc2287682012-04-20 15:46:07 -03001400static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1401 bdaddr_t *src,
1402 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001404 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001406 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001407
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001408 list_for_each_entry(c, &chan_list, global_l) {
1409 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001410
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001411 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412 continue;
1413
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001414 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001415 int src_match, dst_match;
1416 int src_any, dst_any;
1417
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001419 src_match = !bacmp(&bt_sk(sk)->src, src);
1420 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1421 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001422 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001423 return c;
1424 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425
1426 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001427 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1428 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1429 if ((src_match && dst_any) || (src_any && dst_match) ||
1430 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001431 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432 }
1433 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001435 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001436
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001437 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001438}
1439
Andre Guedes8e9f9892012-04-24 21:02:55 -03001440int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1441 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001443 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001445 struct l2cap_conn *conn;
1446 struct hci_conn *hcon;
1447 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001448 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001449 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001450
Andre Guedes8e9f9892012-04-24 21:02:55 -03001451 BT_DBG("%s -> %s (type %u) psm 0x%2.2x", batostr(src), batostr(dst),
Syam Sidhardhanab195162012-07-27 23:51:22 +05301452 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001454 hdev = hci_get_route(dst, src);
1455 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456 return -EHOSTUNREACH;
1457
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001458 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001460 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001461
1462 /* PSM must be odd and lsb of upper byte must be 0 */
1463 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
1464 chan->chan_type != L2CAP_CHAN_RAW) {
1465 err = -EINVAL;
1466 goto done;
1467 }
1468
1469 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1470 err = -EINVAL;
1471 goto done;
1472 }
1473
1474 switch (chan->mode) {
1475 case L2CAP_MODE_BASIC:
1476 break;
1477 case L2CAP_MODE_ERTM:
1478 case L2CAP_MODE_STREAMING:
1479 if (!disable_ertm)
1480 break;
1481 /* fall through */
1482 default:
1483 err = -ENOTSUPP;
1484 goto done;
1485 }
1486
Gustavo Padovan0797e012012-05-27 22:27:54 -03001487 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001488 case BT_CONNECT:
1489 case BT_CONNECT2:
1490 case BT_CONFIG:
1491 /* Already connecting */
1492 err = 0;
1493 goto done;
1494
1495 case BT_CONNECTED:
1496 /* Already connected */
1497 err = -EISCONN;
1498 goto done;
1499
1500 case BT_OPEN:
1501 case BT_BOUND:
1502 /* Can connect */
1503 break;
1504
1505 default:
1506 err = -EBADFD;
1507 goto done;
1508 }
1509
1510 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001511 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001512 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001513 release_sock(sk);
1514
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001515 chan->psm = psm;
1516 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001518 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001519
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001520 if (chan->dcid == L2CAP_CID_LE_DATA)
Andre Guedes8e9f9892012-04-24 21:02:55 -03001521 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001522 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001523 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001524 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001525 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001526
Ville Tervo30e76272011-02-22 16:10:53 -03001527 if (IS_ERR(hcon)) {
1528 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001530 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531
1532 conn = l2cap_conn_add(hcon, 0);
1533 if (!conn) {
1534 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001535 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536 goto done;
1537 }
1538
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001539 if (hcon->type == LE_LINK) {
1540 err = 0;
1541
1542 if (!list_empty(&conn->chan_l)) {
1543 err = -EBUSY;
1544 hci_conn_put(hcon);
1545 }
1546
1547 if (err)
1548 goto done;
1549 }
1550
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551 /* Update source addr of the socket */
1552 bacpy(src, conn->src);
1553
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001554 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001555 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001556 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001557
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001558 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001559 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560
1561 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001562 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001563 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001564 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001565 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001566 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001567 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568 }
1569
Ville Tervo30e76272011-02-22 16:10:53 -03001570 err = 0;
1571
Linus Torvalds1da177e2005-04-16 15:20:36 -07001572done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001573 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001574 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575 hci_dev_put(hdev);
1576 return err;
1577}
1578
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001579int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001580{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001581 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001582 DECLARE_WAITQUEUE(wait, current);
1583 int err = 0;
1584 int timeo = HZ/5;
1585
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001586 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001587 set_current_state(TASK_INTERRUPTIBLE);
1588 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001589 if (!timeo)
1590 timeo = HZ/5;
1591
1592 if (signal_pending(current)) {
1593 err = sock_intr_errno(timeo);
1594 break;
1595 }
1596
1597 release_sock(sk);
1598 timeo = schedule_timeout(timeo);
1599 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001600 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001601
1602 err = sock_error(sk);
1603 if (err)
1604 break;
1605 }
1606 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001607 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001608 return err;
1609}
1610
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001611static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001612{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001613 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001614 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001615
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001616 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001617
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001618 l2cap_chan_lock(chan);
1619
Mat Martineau80909e02012-05-17 20:53:50 -07001620 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001621 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001622 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001623 return;
1624 }
1625
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001626 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001627
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001628 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001629 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001630}
1631
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001632static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001633{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001634 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001635 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001636
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001637 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001638
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001639 l2cap_chan_lock(chan);
1640
Mat Martineau80909e02012-05-17 20:53:50 -07001641 if (!chan->conn) {
1642 l2cap_chan_unlock(chan);
1643 l2cap_chan_put(chan);
1644 return;
1645 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001646
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001647 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001648 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001649 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001650}
1651
Gustavo Padovand6603662012-05-21 13:58:22 -03001652static void l2cap_streaming_send(struct l2cap_chan *chan,
1653 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001654{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001655 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001656 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001657
Mat Martineau37339372012-05-17 20:53:33 -07001658 BT_DBG("chan %p, skbs %p", chan, skbs);
1659
Mat Martineau37339372012-05-17 20:53:33 -07001660 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1661
1662 while (!skb_queue_empty(&chan->tx_q)) {
1663
1664 skb = skb_dequeue(&chan->tx_q);
1665
1666 bt_cb(skb)->control.retries = 1;
1667 control = &bt_cb(skb)->control;
1668
1669 control->reqseq = 0;
1670 control->txseq = chan->next_tx_seq;
1671
1672 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001673
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001674 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001675 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1676 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001677 }
1678
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001679 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001680
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001681 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001682
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001683 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001684 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001685 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001686}
1687
Szymon Janc67c9e842011-07-28 16:24:33 +02001688static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001689{
1690 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001691 struct l2cap_ctrl *control;
1692 int sent = 0;
1693
1694 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001695
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001696 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001697 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001698
Mat Martineau94122bb2012-05-02 09:42:02 -07001699 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1700 return 0;
1701
Mat Martineau18a48e72012-05-17 20:53:34 -07001702 while (chan->tx_send_head &&
1703 chan->unacked_frames < chan->remote_tx_win &&
1704 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001705
Mat Martineau18a48e72012-05-17 20:53:34 -07001706 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001707
Mat Martineau18a48e72012-05-17 20:53:34 -07001708 bt_cb(skb)->control.retries = 1;
1709 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001710
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001711 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001712 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001713
Mat Martineau18a48e72012-05-17 20:53:34 -07001714 control->reqseq = chan->buffer_seq;
1715 chan->last_acked_seq = chan->buffer_seq;
1716 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001717
Mat Martineau18a48e72012-05-17 20:53:34 -07001718 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001719
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001720 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001721 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1722 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001723 }
1724
Mat Martineau18a48e72012-05-17 20:53:34 -07001725 /* Clone after data has been modified. Data is assumed to be
1726 read-only (for locking purposes) on cloned sk_buffs.
1727 */
1728 tx_skb = skb_clone(skb, GFP_KERNEL);
1729
1730 if (!tx_skb)
1731 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001732
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001733 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001734
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001735 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07001736 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03001737 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07001738 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001739
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001740 if (skb_queue_is_last(&chan->tx_q, skb))
1741 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001742 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001743 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07001744
1745 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001746 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001747 }
1748
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001749 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
1750 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07001751
1752 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001753}
1754
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001755static void l2cap_ertm_resend(struct l2cap_chan *chan)
1756{
1757 struct l2cap_ctrl control;
1758 struct sk_buff *skb;
1759 struct sk_buff *tx_skb;
1760 u16 seq;
1761
1762 BT_DBG("chan %p", chan);
1763
1764 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1765 return;
1766
1767 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
1768 seq = l2cap_seq_list_pop(&chan->retrans_list);
1769
1770 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
1771 if (!skb) {
1772 BT_DBG("Error: Can't retransmit seq %d, frame missing",
1773 seq);
1774 continue;
1775 }
1776
1777 bt_cb(skb)->control.retries++;
1778 control = bt_cb(skb)->control;
1779
1780 if (chan->max_tx != 0 &&
1781 bt_cb(skb)->control.retries > chan->max_tx) {
1782 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
1783 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
1784 l2cap_seq_list_clear(&chan->retrans_list);
1785 break;
1786 }
1787
1788 control.reqseq = chan->buffer_seq;
1789 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
1790 control.final = 1;
1791 else
1792 control.final = 0;
1793
1794 if (skb_cloned(skb)) {
1795 /* Cloned sk_buffs are read-only, so we need a
1796 * writeable copy
1797 */
1798 tx_skb = skb_copy(skb, GFP_ATOMIC);
1799 } else {
1800 tx_skb = skb_clone(skb, GFP_ATOMIC);
1801 }
1802
1803 if (!tx_skb) {
1804 l2cap_seq_list_clear(&chan->retrans_list);
1805 break;
1806 }
1807
1808 /* Update skb contents */
1809 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
1810 put_unaligned_le32(__pack_extended_control(&control),
1811 tx_skb->data + L2CAP_HDR_SIZE);
1812 } else {
1813 put_unaligned_le16(__pack_enhanced_control(&control),
1814 tx_skb->data + L2CAP_HDR_SIZE);
1815 }
1816
1817 if (chan->fcs == L2CAP_FCS_CRC16) {
1818 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
1819 put_unaligned_le16(fcs, skb_put(tx_skb,
1820 L2CAP_FCS_SIZE));
1821 }
1822
1823 l2cap_do_send(chan, tx_skb);
1824
1825 BT_DBG("Resent txseq %d", control.txseq);
1826
1827 chan->last_acked_seq = chan->buffer_seq;
1828 }
1829}
1830
Mat Martineauf80842a2012-05-17 20:53:46 -07001831static void l2cap_retransmit(struct l2cap_chan *chan,
1832 struct l2cap_ctrl *control)
1833{
1834 BT_DBG("chan %p, control %p", chan, control);
1835
1836 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
1837 l2cap_ertm_resend(chan);
1838}
1839
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001840static void l2cap_retransmit_all(struct l2cap_chan *chan,
1841 struct l2cap_ctrl *control)
1842{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001843 struct sk_buff *skb;
1844
1845 BT_DBG("chan %p, control %p", chan, control);
1846
1847 if (control->poll)
1848 set_bit(CONN_SEND_FBIT, &chan->conn_state);
1849
1850 l2cap_seq_list_clear(&chan->retrans_list);
1851
1852 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1853 return;
1854
1855 if (chan->unacked_frames) {
1856 skb_queue_walk(&chan->tx_q, skb) {
1857 if (bt_cb(skb)->control.txseq == control->reqseq ||
1858 skb == chan->tx_send_head)
1859 break;
1860 }
1861
1862 skb_queue_walk_from(&chan->tx_q, skb) {
1863 if (skb == chan->tx_send_head)
1864 break;
1865
1866 l2cap_seq_list_append(&chan->retrans_list,
1867 bt_cb(skb)->control.txseq);
1868 }
1869
1870 l2cap_ertm_resend(chan);
1871 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001872}
1873
Szymon Jancb17e73b2012-01-11 10:59:47 +01001874static void l2cap_send_ack(struct l2cap_chan *chan)
1875{
Mat Martineau0a0aba42012-05-17 20:53:39 -07001876 struct l2cap_ctrl control;
1877 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
1878 chan->last_acked_seq);
1879 int threshold;
1880
1881 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
1882 chan, chan->last_acked_seq, chan->buffer_seq);
1883
1884 memset(&control, 0, sizeof(control));
1885 control.sframe = 1;
1886
1887 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
1888 chan->rx_state == L2CAP_RX_STATE_RECV) {
1889 __clear_ack_timer(chan);
1890 control.super = L2CAP_SUPER_RNR;
1891 control.reqseq = chan->buffer_seq;
1892 l2cap_send_sframe(chan, &control);
1893 } else {
1894 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
1895 l2cap_ertm_send(chan);
1896 /* If any i-frames were sent, they included an ack */
1897 if (chan->buffer_seq == chan->last_acked_seq)
1898 frames_to_ack = 0;
1899 }
1900
Mat Martineauc20f8e32012-07-10 05:47:07 -07001901 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07001902 * Calculate without mul or div
1903 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07001904 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07001905 threshold += threshold << 1;
1906 threshold >>= 2;
1907
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001908 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07001909 threshold);
1910
1911 if (frames_to_ack >= threshold) {
1912 __clear_ack_timer(chan);
1913 control.super = L2CAP_SUPER_RR;
1914 control.reqseq = chan->buffer_seq;
1915 l2cap_send_sframe(chan, &control);
1916 frames_to_ack = 0;
1917 }
1918
1919 if (frames_to_ack)
1920 __set_ack_timer(chan);
1921 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01001922}
1923
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001924static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
1925 struct msghdr *msg, int len,
1926 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001927{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02001928 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001929 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03001930 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001931
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001932 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001933 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934
1935 sent += count;
1936 len -= count;
1937
1938 /* Continuation fragments (no L2CAP header) */
1939 frag = &skb_shinfo(skb)->frag_list;
1940 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001941 struct sk_buff *tmp;
1942
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943 count = min_t(unsigned int, conn->mtu, len);
1944
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001945 tmp = chan->ops->alloc_skb(chan, count,
1946 msg->msg_flags & MSG_DONTWAIT);
1947 if (IS_ERR(tmp))
1948 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001949
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001950 *frag = tmp;
1951
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001952 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1953 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001954
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001955 (*frag)->priority = skb->priority;
1956
Linus Torvalds1da177e2005-04-16 15:20:36 -07001957 sent += count;
1958 len -= count;
1959
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03001960 skb->len += (*frag)->len;
1961 skb->data_len += (*frag)->len;
1962
Linus Torvalds1da177e2005-04-16 15:20:36 -07001963 frag = &(*frag)->next;
1964 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965
1966 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001967}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001968
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001969static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001970 struct msghdr *msg, size_t len,
1971 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001972{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001973 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001974 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03001975 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001976 struct l2cap_hdr *lh;
1977
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001978 BT_DBG("chan %p len %zu priority %u", chan, len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001979
1980 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001981
1982 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03001983 msg->msg_flags & MSG_DONTWAIT);
1984 if (IS_ERR(skb))
1985 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001986
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001987 skb->priority = priority;
1988
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001989 /* Create L2CAP header */
1990 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001991 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03001992 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
1993 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001994
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02001995 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001996 if (unlikely(err < 0)) {
1997 kfree_skb(skb);
1998 return ERR_PTR(err);
1999 }
2000 return skb;
2001}
2002
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002003static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002004 struct msghdr *msg, size_t len,
2005 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002006{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002007 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002008 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002009 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002010 struct l2cap_hdr *lh;
2011
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002012 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002013
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002014 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002015
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002016 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002017 msg->msg_flags & MSG_DONTWAIT);
2018 if (IS_ERR(skb))
2019 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002020
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002021 skb->priority = priority;
2022
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002023 /* Create L2CAP header */
2024 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002025 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002026 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002027
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002028 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002029 if (unlikely(err < 0)) {
2030 kfree_skb(skb);
2031 return ERR_PTR(err);
2032 }
2033 return skb;
2034}
2035
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002036static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002037 struct msghdr *msg, size_t len,
2038 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002039{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002040 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002041 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002042 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002043 struct l2cap_hdr *lh;
2044
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002045 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002046
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002047 if (!conn)
2048 return ERR_PTR(-ENOTCONN);
2049
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002050 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002051
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002052 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002053 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002054
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002055 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002056 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002057
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002058 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002059
2060 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002061 msg->msg_flags & MSG_DONTWAIT);
2062 if (IS_ERR(skb))
2063 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002064
2065 /* Create L2CAP header */
2066 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002067 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002068 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002069
Mat Martineau18a48e72012-05-17 20:53:34 -07002070 /* Control header is populated later */
2071 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2072 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2073 else
2074 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002075
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002076 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002077 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002078
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002079 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002080 if (unlikely(err < 0)) {
2081 kfree_skb(skb);
2082 return ERR_PTR(err);
2083 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002084
Mat Martineau18a48e72012-05-17 20:53:34 -07002085 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002086 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002087 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002088}
2089
Mat Martineau94122bb2012-05-02 09:42:02 -07002090static int l2cap_segment_sdu(struct l2cap_chan *chan,
2091 struct sk_buff_head *seg_queue,
2092 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002093{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002094 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002095 u16 sdu_len;
2096 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002097 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002098
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002099 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002100
Mat Martineau94122bb2012-05-02 09:42:02 -07002101 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2102 * so fragmented skbs are not used. The HCI layer's handling
2103 * of fragmented skbs is not compatible with ERTM's queueing.
2104 */
2105
2106 /* PDU size is derived from the HCI MTU */
2107 pdu_len = chan->conn->mtu;
2108
2109 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
2110
2111 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002112 if (chan->fcs)
2113 pdu_len -= L2CAP_FCS_SIZE;
2114
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002115 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002116
2117 /* Remote device may have requested smaller PDUs */
2118 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2119
2120 if (len <= pdu_len) {
2121 sar = L2CAP_SAR_UNSEGMENTED;
2122 sdu_len = 0;
2123 pdu_len = len;
2124 } else {
2125 sar = L2CAP_SAR_START;
2126 sdu_len = len;
2127 pdu_len -= L2CAP_SDULEN_SIZE;
2128 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002129
2130 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002131 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002132
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002133 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002134 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002135 return PTR_ERR(skb);
2136 }
2137
Mat Martineau94122bb2012-05-02 09:42:02 -07002138 bt_cb(skb)->control.sar = sar;
2139 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002140
Mat Martineau94122bb2012-05-02 09:42:02 -07002141 len -= pdu_len;
2142 if (sdu_len) {
2143 sdu_len = 0;
2144 pdu_len += L2CAP_SDULEN_SIZE;
2145 }
2146
2147 if (len <= pdu_len) {
2148 sar = L2CAP_SAR_END;
2149 pdu_len = len;
2150 } else {
2151 sar = L2CAP_SAR_CONTINUE;
2152 }
2153 }
2154
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002155 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002156}
2157
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002158int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
2159 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002160{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002161 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002162 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002163 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002164
2165 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002166 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002167 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002168 if (IS_ERR(skb))
2169 return PTR_ERR(skb);
2170
2171 l2cap_do_send(chan, skb);
2172 return len;
2173 }
2174
2175 switch (chan->mode) {
2176 case L2CAP_MODE_BASIC:
2177 /* Check outgoing MTU */
2178 if (len > chan->omtu)
2179 return -EMSGSIZE;
2180
2181 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002182 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002183 if (IS_ERR(skb))
2184 return PTR_ERR(skb);
2185
2186 l2cap_do_send(chan, skb);
2187 err = len;
2188 break;
2189
2190 case L2CAP_MODE_ERTM:
2191 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002192 /* Check outgoing MTU */
2193 if (len > chan->omtu) {
2194 err = -EMSGSIZE;
2195 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002196 }
2197
Mat Martineau94122bb2012-05-02 09:42:02 -07002198 __skb_queue_head_init(&seg_queue);
2199
2200 /* Do segmentation before calling in to the state machine,
2201 * since it's possible to block while waiting for memory
2202 * allocation.
2203 */
2204 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2205
2206 /* The channel could have been closed while segmenting,
2207 * check that it is still connected.
2208 */
2209 if (chan->state != BT_CONNECTED) {
2210 __skb_queue_purge(&seg_queue);
2211 err = -ENOTCONN;
2212 }
2213
2214 if (err)
2215 break;
2216
Mat Martineau37339372012-05-17 20:53:33 -07002217 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002218 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002219 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002220 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002221
Gustavo Padovand6603662012-05-21 13:58:22 -03002222 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002223
Mat Martineau94122bb2012-05-02 09:42:02 -07002224 /* If the skbs were not queued for sending, they'll still be in
2225 * seg_queue and need to be purged.
2226 */
2227 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002228 break;
2229
2230 default:
2231 BT_DBG("bad state %1.1x", chan->mode);
2232 err = -EBADFD;
2233 }
2234
2235 return err;
2236}
2237
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002238static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2239{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002240 struct l2cap_ctrl control;
2241 u16 seq;
2242
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002243 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002244
2245 memset(&control, 0, sizeof(control));
2246 control.sframe = 1;
2247 control.super = L2CAP_SUPER_SREJ;
2248
2249 for (seq = chan->expected_tx_seq; seq != txseq;
2250 seq = __next_seq(chan, seq)) {
2251 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2252 control.reqseq = seq;
2253 l2cap_send_sframe(chan, &control);
2254 l2cap_seq_list_append(&chan->srej_list, seq);
2255 }
2256 }
2257
2258 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002259}
2260
2261static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2262{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002263 struct l2cap_ctrl control;
2264
2265 BT_DBG("chan %p", chan);
2266
2267 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2268 return;
2269
2270 memset(&control, 0, sizeof(control));
2271 control.sframe = 1;
2272 control.super = L2CAP_SUPER_SREJ;
2273 control.reqseq = chan->srej_list.tail;
2274 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002275}
2276
2277static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2278{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002279 struct l2cap_ctrl control;
2280 u16 initial_head;
2281 u16 seq;
2282
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002283 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002284
2285 memset(&control, 0, sizeof(control));
2286 control.sframe = 1;
2287 control.super = L2CAP_SUPER_SREJ;
2288
2289 /* Capture initial list head to allow only one pass through the list. */
2290 initial_head = chan->srej_list.head;
2291
2292 do {
2293 seq = l2cap_seq_list_pop(&chan->srej_list);
2294 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2295 break;
2296
2297 control.reqseq = seq;
2298 l2cap_send_sframe(chan, &control);
2299 l2cap_seq_list_append(&chan->srej_list, seq);
2300 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002301}
2302
Mat Martineau608bcc62012-05-17 20:53:32 -07002303static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2304{
2305 struct sk_buff *acked_skb;
2306 u16 ackseq;
2307
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002308 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002309
2310 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2311 return;
2312
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002313 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002314 chan->expected_ack_seq, chan->unacked_frames);
2315
2316 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2317 ackseq = __next_seq(chan, ackseq)) {
2318
2319 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2320 if (acked_skb) {
2321 skb_unlink(acked_skb, &chan->tx_q);
2322 kfree_skb(acked_skb);
2323 chan->unacked_frames--;
2324 }
2325 }
2326
2327 chan->expected_ack_seq = reqseq;
2328
2329 if (chan->unacked_frames == 0)
2330 __clear_retrans_timer(chan);
2331
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002332 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002333}
2334
2335static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2336{
2337 BT_DBG("chan %p", chan);
2338
2339 chan->expected_tx_seq = chan->buffer_seq;
2340 l2cap_seq_list_clear(&chan->srej_list);
2341 skb_queue_purge(&chan->srej_q);
2342 chan->rx_state = L2CAP_RX_STATE_RECV;
2343}
2344
Gustavo Padovand6603662012-05-21 13:58:22 -03002345static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2346 struct l2cap_ctrl *control,
2347 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002348{
Mat Martineau608bcc62012-05-17 20:53:32 -07002349 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2350 event);
2351
2352 switch (event) {
2353 case L2CAP_EV_DATA_REQUEST:
2354 if (chan->tx_send_head == NULL)
2355 chan->tx_send_head = skb_peek(skbs);
2356
2357 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2358 l2cap_ertm_send(chan);
2359 break;
2360 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2361 BT_DBG("Enter LOCAL_BUSY");
2362 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2363
2364 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2365 /* The SREJ_SENT state must be aborted if we are to
2366 * enter the LOCAL_BUSY state.
2367 */
2368 l2cap_abort_rx_srej_sent(chan);
2369 }
2370
2371 l2cap_send_ack(chan);
2372
2373 break;
2374 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2375 BT_DBG("Exit LOCAL_BUSY");
2376 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2377
2378 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2379 struct l2cap_ctrl local_control;
2380
2381 memset(&local_control, 0, sizeof(local_control));
2382 local_control.sframe = 1;
2383 local_control.super = L2CAP_SUPER_RR;
2384 local_control.poll = 1;
2385 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002386 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002387
2388 chan->retry_count = 1;
2389 __set_monitor_timer(chan);
2390 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2391 }
2392 break;
2393 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2394 l2cap_process_reqseq(chan, control->reqseq);
2395 break;
2396 case L2CAP_EV_EXPLICIT_POLL:
2397 l2cap_send_rr_or_rnr(chan, 1);
2398 chan->retry_count = 1;
2399 __set_monitor_timer(chan);
2400 __clear_ack_timer(chan);
2401 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2402 break;
2403 case L2CAP_EV_RETRANS_TO:
2404 l2cap_send_rr_or_rnr(chan, 1);
2405 chan->retry_count = 1;
2406 __set_monitor_timer(chan);
2407 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2408 break;
2409 case L2CAP_EV_RECV_FBIT:
2410 /* Nothing to process */
2411 break;
2412 default:
2413 break;
2414 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002415}
2416
Gustavo Padovand6603662012-05-21 13:58:22 -03002417static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2418 struct l2cap_ctrl *control,
2419 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002420{
Mat Martineau608bcc62012-05-17 20:53:32 -07002421 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2422 event);
2423
2424 switch (event) {
2425 case L2CAP_EV_DATA_REQUEST:
2426 if (chan->tx_send_head == NULL)
2427 chan->tx_send_head = skb_peek(skbs);
2428 /* Queue data, but don't send. */
2429 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2430 break;
2431 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2432 BT_DBG("Enter LOCAL_BUSY");
2433 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2434
2435 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2436 /* The SREJ_SENT state must be aborted if we are to
2437 * enter the LOCAL_BUSY state.
2438 */
2439 l2cap_abort_rx_srej_sent(chan);
2440 }
2441
2442 l2cap_send_ack(chan);
2443
2444 break;
2445 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2446 BT_DBG("Exit LOCAL_BUSY");
2447 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2448
2449 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2450 struct l2cap_ctrl local_control;
2451 memset(&local_control, 0, sizeof(local_control));
2452 local_control.sframe = 1;
2453 local_control.super = L2CAP_SUPER_RR;
2454 local_control.poll = 1;
2455 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002456 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002457
2458 chan->retry_count = 1;
2459 __set_monitor_timer(chan);
2460 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2461 }
2462 break;
2463 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2464 l2cap_process_reqseq(chan, control->reqseq);
2465
2466 /* Fall through */
2467
2468 case L2CAP_EV_RECV_FBIT:
2469 if (control && control->final) {
2470 __clear_monitor_timer(chan);
2471 if (chan->unacked_frames > 0)
2472 __set_retrans_timer(chan);
2473 chan->retry_count = 0;
2474 chan->tx_state = L2CAP_TX_STATE_XMIT;
2475 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2476 }
2477 break;
2478 case L2CAP_EV_EXPLICIT_POLL:
2479 /* Ignore */
2480 break;
2481 case L2CAP_EV_MONITOR_TO:
2482 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2483 l2cap_send_rr_or_rnr(chan, 1);
2484 __set_monitor_timer(chan);
2485 chan->retry_count++;
2486 } else {
2487 l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
2488 }
2489 break;
2490 default:
2491 break;
2492 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002493}
2494
Gustavo Padovand6603662012-05-21 13:58:22 -03002495static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2496 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002497{
Mat Martineau608bcc62012-05-17 20:53:32 -07002498 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2499 chan, control, skbs, event, chan->tx_state);
2500
2501 switch (chan->tx_state) {
2502 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002503 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002504 break;
2505 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002506 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002507 break;
2508 default:
2509 /* Ignore event */
2510 break;
2511 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002512}
2513
Mat Martineau4b51dae92012-05-17 20:53:37 -07002514static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2515 struct l2cap_ctrl *control)
2516{
2517 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002518 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002519}
2520
Mat Martineauf80842a2012-05-17 20:53:46 -07002521static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2522 struct l2cap_ctrl *control)
2523{
2524 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002525 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002526}
2527
Linus Torvalds1da177e2005-04-16 15:20:36 -07002528/* Copy frame to all raw sockets on that connection */
2529static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2530{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002531 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002532 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002533
2534 BT_DBG("conn %p", conn);
2535
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002536 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002537
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002538 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002539 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002540 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002541 continue;
2542
2543 /* Don't send frame to the socket it came from */
2544 if (skb->sk == sk)
2545 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002546 nskb = skb_clone(skb, GFP_ATOMIC);
2547 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002548 continue;
2549
Gustavo Padovan80b98022012-05-27 22:27:51 -03002550 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551 kfree_skb(nskb);
2552 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002553
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002554 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002555}
2556
2557/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002558static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2559 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002560{
2561 struct sk_buff *skb, **frag;
2562 struct l2cap_cmd_hdr *cmd;
2563 struct l2cap_hdr *lh;
2564 int len, count;
2565
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002566 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2567 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002568
2569 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2570 count = min_t(unsigned int, conn->mtu, len);
2571
2572 skb = bt_skb_alloc(count, GFP_ATOMIC);
2573 if (!skb)
2574 return NULL;
2575
2576 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002577 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002578
2579 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002580 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002581 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002582 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002583
2584 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2585 cmd->code = code;
2586 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002587 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002588
2589 if (dlen) {
2590 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2591 memcpy(skb_put(skb, count), data, count);
2592 data += count;
2593 }
2594
2595 len -= skb->len;
2596
2597 /* Continuation fragments (no L2CAP header) */
2598 frag = &skb_shinfo(skb)->frag_list;
2599 while (len) {
2600 count = min_t(unsigned int, conn->mtu, len);
2601
2602 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2603 if (!*frag)
2604 goto fail;
2605
2606 memcpy(skb_put(*frag, count), data, count);
2607
2608 len -= count;
2609 data += count;
2610
2611 frag = &(*frag)->next;
2612 }
2613
2614 return skb;
2615
2616fail:
2617 kfree_skb(skb);
2618 return NULL;
2619}
2620
2621static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2622{
2623 struct l2cap_conf_opt *opt = *ptr;
2624 int len;
2625
2626 len = L2CAP_CONF_OPT_SIZE + opt->len;
2627 *ptr += len;
2628
2629 *type = opt->type;
2630 *olen = opt->len;
2631
2632 switch (opt->len) {
2633 case 1:
2634 *val = *((u8 *) opt->val);
2635 break;
2636
2637 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002638 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002639 break;
2640
2641 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002642 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002643 break;
2644
2645 default:
2646 *val = (unsigned long) opt->val;
2647 break;
2648 }
2649
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002650 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002651 return len;
2652}
2653
Linus Torvalds1da177e2005-04-16 15:20:36 -07002654static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2655{
2656 struct l2cap_conf_opt *opt = *ptr;
2657
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002658 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002659
2660 opt->type = type;
2661 opt->len = len;
2662
2663 switch (len) {
2664 case 1:
2665 *((u8 *) opt->val) = val;
2666 break;
2667
2668 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002669 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002670 break;
2671
2672 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002673 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002674 break;
2675
2676 default:
2677 memcpy(opt->val, (void *) val, len);
2678 break;
2679 }
2680
2681 *ptr += L2CAP_CONF_OPT_SIZE + len;
2682}
2683
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002684static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2685{
2686 struct l2cap_conf_efs efs;
2687
Szymon Janc1ec918c2011-11-16 09:32:21 +01002688 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002689 case L2CAP_MODE_ERTM:
2690 efs.id = chan->local_id;
2691 efs.stype = chan->local_stype;
2692 efs.msdu = cpu_to_le16(chan->local_msdu);
2693 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002694 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
2695 efs.flush_to = __constant_cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002696 break;
2697
2698 case L2CAP_MODE_STREAMING:
2699 efs.id = 1;
2700 efs.stype = L2CAP_SERV_BESTEFFORT;
2701 efs.msdu = cpu_to_le16(chan->local_msdu);
2702 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2703 efs.acc_lat = 0;
2704 efs.flush_to = 0;
2705 break;
2706
2707 default:
2708 return;
2709 }
2710
2711 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
2712 (unsigned long) &efs);
2713}
2714
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002715static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002716{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002717 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07002718 ack_timer.work);
2719 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002720
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02002721 BT_DBG("chan %p", chan);
2722
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002723 l2cap_chan_lock(chan);
2724
Mat Martineau03625202012-05-17 20:53:51 -07002725 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2726 chan->last_acked_seq);
2727
2728 if (frames_to_ack)
2729 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002730
2731 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01002732 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002733}
2734
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03002735int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002736{
Mat Martineau3c588192012-04-11 10:48:42 -07002737 int err;
2738
Mat Martineau105bdf92012-04-27 16:50:48 -07002739 chan->next_tx_seq = 0;
2740 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002741 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002742 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002743 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002744 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07002745 chan->last_acked_seq = 0;
2746 chan->sdu = NULL;
2747 chan->sdu_last_frag = NULL;
2748 chan->sdu_len = 0;
2749
Mat Martineaud34c34f2012-05-14 14:49:27 -07002750 skb_queue_head_init(&chan->tx_q);
2751
Mat Martineau105bdf92012-04-27 16:50:48 -07002752 if (chan->mode != L2CAP_MODE_ERTM)
2753 return 0;
2754
2755 chan->rx_state = L2CAP_RX_STATE_RECV;
2756 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002757
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002758 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
2759 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
2760 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002761
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03002762 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002763
Mat Martineau3c588192012-04-11 10:48:42 -07002764 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
2765 if (err < 0)
2766 return err;
2767
Mat Martineau9dc9aff2012-05-17 16:20:14 -07002768 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
2769 if (err < 0)
2770 l2cap_seq_list_free(&chan->srej_list);
2771
2772 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002773}
2774
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002775static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2776{
2777 switch (mode) {
2778 case L2CAP_MODE_STREAMING:
2779 case L2CAP_MODE_ERTM:
2780 if (l2cap_mode_supported(mode, remote_feat_mask))
2781 return mode;
2782 /* fall through */
2783 default:
2784 return L2CAP_MODE_BASIC;
2785 }
2786}
2787
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002788static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
2789{
2790 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
2791}
2792
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002793static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
2794{
2795 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
2796}
2797
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002798static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
2799{
2800 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002801 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002802 /* use extended control field */
2803 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002804 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
2805 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002806 chan->tx_win = min_t(u16, chan->tx_win,
2807 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002808 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
2809 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07002810 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002811}
2812
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03002813static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002814{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002815 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002816 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002818 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002819
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03002820 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002821
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002822 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002823 goto done;
2824
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002825 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002826 case L2CAP_MODE_STREAMING:
2827 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002828 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002829 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002830
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002831 if (__l2cap_efs_supported(chan))
2832 set_bit(FLAG_EFS_ENABLE, &chan->flags);
2833
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002834 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002835 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002836 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002837 break;
2838 }
2839
2840done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002841 if (chan->imtu != L2CAP_DEFAULT_MTU)
2842 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02002843
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002844 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002845 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002846 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
2847 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002848 break;
2849
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002850 rfc.mode = L2CAP_MODE_BASIC;
2851 rfc.txwin_size = 0;
2852 rfc.max_transmit = 0;
2853 rfc.retrans_timeout = 0;
2854 rfc.monitor_timeout = 0;
2855 rfc.max_pdu_size = 0;
2856
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002857 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2858 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002859 break;
2860
2861 case L2CAP_MODE_ERTM:
2862 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002863 rfc.max_transmit = chan->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002864 rfc.retrans_timeout = 0;
2865 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002866
2867 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
2868 L2CAP_EXT_HDR_SIZE -
2869 L2CAP_SDULEN_SIZE -
2870 L2CAP_FCS_SIZE);
2871 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002872
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002873 l2cap_txwin_setup(chan);
2874
2875 rfc.txwin_size = min_t(u16, chan->tx_win,
2876 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002877
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002878 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2879 (unsigned long) &rfc);
2880
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002881 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2882 l2cap_add_opt_efs(&ptr, chan);
2883
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002884 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002885 break;
2886
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002887 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002888 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002889 chan->fcs = L2CAP_FCS_NONE;
2890 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002891 }
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002892
2893 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2894 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
2895 chan->tx_win);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002896 break;
2897
2898 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07002899 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002900 rfc.mode = L2CAP_MODE_STREAMING;
2901 rfc.txwin_size = 0;
2902 rfc.max_transmit = 0;
2903 rfc.retrans_timeout = 0;
2904 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002905
2906 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
2907 L2CAP_EXT_HDR_SIZE -
2908 L2CAP_SDULEN_SIZE -
2909 L2CAP_FCS_SIZE);
2910 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002911
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002912 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2913 (unsigned long) &rfc);
2914
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002915 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2916 l2cap_add_opt_efs(&ptr, chan);
2917
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002918 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002919 break;
2920
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002921 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002922 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002923 chan->fcs = L2CAP_FCS_NONE;
2924 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002925 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002926 break;
2927 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002928
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002929 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03002930 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002931
2932 return ptr - data;
2933}
2934
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002935static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002936{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002937 struct l2cap_conf_rsp *rsp = data;
2938 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002939 void *req = chan->conf_req;
2940 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002941 int type, hint, olen;
2942 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002943 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002944 struct l2cap_conf_efs efs;
2945 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02002946 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002947 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002948 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002949
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002950 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002951
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002952 while (len >= L2CAP_CONF_OPT_SIZE) {
2953 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002954
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002955 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002956 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002957
2958 switch (type) {
2959 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002960 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002961 break;
2962
2963 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002964 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002965 break;
2966
2967 case L2CAP_CONF_QOS:
2968 break;
2969
Marcel Holtmann6464f352007-10-20 13:39:51 +02002970 case L2CAP_CONF_RFC:
2971 if (olen == sizeof(rfc))
2972 memcpy(&rfc, (void *) val, olen);
2973 break;
2974
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002975 case L2CAP_CONF_FCS:
2976 if (val == L2CAP_FCS_NONE)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002977 set_bit(CONF_NO_FCS_RECV, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002978 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002979
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002980 case L2CAP_CONF_EFS:
2981 remote_efs = 1;
2982 if (olen == sizeof(efs))
2983 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002984 break;
2985
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002986 case L2CAP_CONF_EWS:
2987 if (!enable_hs)
2988 return -ECONNREFUSED;
2989
2990 set_bit(FLAG_EXT_CTRL, &chan->flags);
2991 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002992 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002993 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002994 break;
2995
2996 default:
2997 if (hint)
2998 break;
2999
3000 result = L2CAP_CONF_UNKNOWN;
3001 *((u8 *) ptr++) = type;
3002 break;
3003 }
3004 }
3005
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003006 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003007 goto done;
3008
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003009 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003010 case L2CAP_MODE_STREAMING:
3011 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003012 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003013 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003014 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003015 break;
3016 }
3017
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003018 if (remote_efs) {
3019 if (__l2cap_efs_supported(chan))
3020 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3021 else
3022 return -ECONNREFUSED;
3023 }
3024
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003025 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003026 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003027
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003028 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003029 }
3030
3031done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003032 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003033 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003034 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003035
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003036 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003037 return -ECONNREFUSED;
3038
3039 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3040 sizeof(rfc), (unsigned long) &rfc);
3041 }
3042
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003043 if (result == L2CAP_CONF_SUCCESS) {
3044 /* Configure output options and let the other side know
3045 * which ones we don't like. */
3046
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003047 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3048 result = L2CAP_CONF_UNACCEPT;
3049 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003050 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003051 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003052 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003053 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003054
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003055 if (remote_efs) {
3056 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
3057 efs.stype != L2CAP_SERV_NOTRAFIC &&
3058 efs.stype != chan->local_stype) {
3059
3060 result = L2CAP_CONF_UNACCEPT;
3061
3062 if (chan->num_conf_req >= 1)
3063 return -ECONNREFUSED;
3064
3065 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003066 sizeof(efs),
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003067 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003068 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003069 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003070 result = L2CAP_CONF_PENDING;
3071 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003072 }
3073 }
3074
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003075 switch (rfc.mode) {
3076 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003077 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003078 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003079 break;
3080
3081 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003082 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3083 chan->remote_tx_win = rfc.txwin_size;
3084 else
3085 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3086
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003087 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003088
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003089 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
3090 chan->conn->mtu -
3091 L2CAP_EXT_HDR_SIZE -
3092 L2CAP_SDULEN_SIZE -
3093 L2CAP_FCS_SIZE);
3094 rfc.max_pdu_size = cpu_to_le16(size);
3095 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003096
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003097 rfc.retrans_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003098 __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003099 rfc.monitor_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003100 __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003101
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003102 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003103
3104 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3105 sizeof(rfc), (unsigned long) &rfc);
3106
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003107 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3108 chan->remote_id = efs.id;
3109 chan->remote_stype = efs.stype;
3110 chan->remote_msdu = le16_to_cpu(efs.msdu);
3111 chan->remote_flush_to =
3112 le32_to_cpu(efs.flush_to);
3113 chan->remote_acc_lat =
3114 le32_to_cpu(efs.acc_lat);
3115 chan->remote_sdu_itime =
3116 le32_to_cpu(efs.sdu_itime);
3117 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
3118 sizeof(efs), (unsigned long) &efs);
3119 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003120 break;
3121
3122 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003123 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
3124 chan->conn->mtu -
3125 L2CAP_EXT_HDR_SIZE -
3126 L2CAP_SDULEN_SIZE -
3127 L2CAP_FCS_SIZE);
3128 rfc.max_pdu_size = cpu_to_le16(size);
3129 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003130
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003131 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003132
3133 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3134 sizeof(rfc), (unsigned long) &rfc);
3135
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003136 break;
3137
3138 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003139 result = L2CAP_CONF_UNACCEPT;
3140
3141 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003142 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003143 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003144
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003145 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003146 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003147 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003148 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003149 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003150 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003151
3152 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003153}
3154
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003155static 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 -03003156{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003157 struct l2cap_conf_req *req = data;
3158 void *ptr = req->data;
3159 int type, olen;
3160 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003161 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003162 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003163
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003164 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003165
3166 while (len >= L2CAP_CONF_OPT_SIZE) {
3167 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3168
3169 switch (type) {
3170 case L2CAP_CONF_MTU:
3171 if (val < L2CAP_DEFAULT_MIN_MTU) {
3172 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003173 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003174 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003175 chan->imtu = val;
3176 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003177 break;
3178
3179 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003180 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003181 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003182 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003183 break;
3184
3185 case L2CAP_CONF_RFC:
3186 if (olen == sizeof(rfc))
3187 memcpy(&rfc, (void *)val, olen);
3188
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003189 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003190 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003191 return -ECONNREFUSED;
3192
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003193 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003194
3195 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3196 sizeof(rfc), (unsigned long) &rfc);
3197 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003198
3199 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003200 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003201 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003202 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003203 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003204
3205 case L2CAP_CONF_EFS:
3206 if (olen == sizeof(efs))
3207 memcpy(&efs, (void *)val, olen);
3208
3209 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
3210 efs.stype != L2CAP_SERV_NOTRAFIC &&
3211 efs.stype != chan->local_stype)
3212 return -ECONNREFUSED;
3213
3214 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
3215 sizeof(efs), (unsigned long) &efs);
3216 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003217 }
3218 }
3219
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003220 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003221 return -ECONNREFUSED;
3222
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003223 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003224
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003225 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003226 switch (rfc.mode) {
3227 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003228 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3229 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3230 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003231 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3232 chan->ack_win = min_t(u16, chan->ack_win,
3233 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003234
3235 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3236 chan->local_msdu = le16_to_cpu(efs.msdu);
3237 chan->local_sdu_itime =
3238 le32_to_cpu(efs.sdu_itime);
3239 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3240 chan->local_flush_to =
3241 le32_to_cpu(efs.flush_to);
3242 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003243 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003244
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003245 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003246 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003247 }
3248 }
3249
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003250 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003251 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003252
3253 return ptr - data;
3254}
3255
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003256static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003257{
3258 struct l2cap_conf_rsp *rsp = data;
3259 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003260
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003261 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003262
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003263 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003264 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003265 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003266
3267 return ptr - data;
3268}
3269
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003270void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003271{
3272 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003273 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003274 u8 buf[128];
3275
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003276 rsp.scid = cpu_to_le16(chan->dcid);
3277 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003278 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3279 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003280 l2cap_send_cmd(conn, chan->ident,
3281 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
3282
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003283 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003284 return;
3285
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003286 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3287 l2cap_build_conf_req(chan, buf), buf);
3288 chan->num_conf_req++;
3289}
3290
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003291static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003292{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003293 int type, olen;
3294 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003295 /* Use sane default values in case a misbehaving remote device
3296 * did not send an RFC or extended window size option.
3297 */
3298 u16 txwin_ext = chan->ack_win;
3299 struct l2cap_conf_rfc rfc = {
3300 .mode = chan->mode,
3301 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3302 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3303 .max_pdu_size = cpu_to_le16(chan->imtu),
3304 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3305 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003306
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003307 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003308
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003309 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003310 return;
3311
3312 while (len >= L2CAP_CONF_OPT_SIZE) {
3313 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3314
Mat Martineauc20f8e32012-07-10 05:47:07 -07003315 switch (type) {
3316 case L2CAP_CONF_RFC:
3317 if (olen == sizeof(rfc))
3318 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003319 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003320 case L2CAP_CONF_EWS:
3321 txwin_ext = val;
3322 break;
3323 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003324 }
3325
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003326 switch (rfc.mode) {
3327 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003328 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3329 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003330 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3331 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3332 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3333 else
3334 chan->ack_win = min_t(u16, chan->ack_win,
3335 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003336 break;
3337 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003338 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003339 }
3340}
3341
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003342static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3343{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003344 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003345
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003346 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003347 return 0;
3348
3349 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
3350 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003351 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003352
3353 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003354 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003355
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003356 l2cap_conn_start(conn);
3357 }
3358
3359 return 0;
3360}
3361
Linus Torvalds1da177e2005-04-16 15:20:36 -07003362static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3363{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003364 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3365 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003366 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003367 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003368 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003369
3370 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003371 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003372
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003373 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003374
3375 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003376 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003377 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003378 result = L2CAP_CR_BAD_PSM;
3379 goto sendresp;
3380 }
3381
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003382 parent = pchan->sk;
3383
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003384 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003385 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003386
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003387 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003388 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003389 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003390 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003391 result = L2CAP_CR_SEC_BLOCK;
3392 goto response;
3393 }
3394
Linus Torvalds1da177e2005-04-16 15:20:36 -07003395 result = L2CAP_CR_NO_MEM;
3396
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003397 /* Check if we already have channel with that dcid */
3398 if (__l2cap_get_chan_by_dcid(conn, scid))
3399 goto response;
3400
Gustavo Padovan80b98022012-05-27 22:27:51 -03003401 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003402 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003403 goto response;
3404
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003405 sk = chan->sk;
3406
Linus Torvalds1da177e2005-04-16 15:20:36 -07003407 hci_conn_hold(conn->hcon);
3408
Linus Torvalds1da177e2005-04-16 15:20:36 -07003409 bacpy(&bt_sk(sk)->src, conn->src);
3410 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003411 chan->psm = psm;
3412 chan->dcid = scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003413
Gustavo F. Padovand1010242011-03-25 00:39:48 -03003414 bt_accept_enqueue(parent, sk);
3415
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003416 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003417
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003418 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003419
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003420 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003421
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003422 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003423
Marcel Holtmann984947d2009-02-06 23:35:19 +01003424 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003425 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003426 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003427 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003428 result = L2CAP_CR_PEND;
3429 status = L2CAP_CS_AUTHOR_PEND;
3430 parent->sk_data_ready(parent, 0);
3431 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003432 __l2cap_state_change(chan, BT_CONFIG);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003433 result = L2CAP_CR_SUCCESS;
3434 status = L2CAP_CS_NO_INFO;
3435 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003436 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003437 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003438 result = L2CAP_CR_PEND;
3439 status = L2CAP_CS_AUTHEN_PEND;
3440 }
3441 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003442 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003443 result = L2CAP_CR_PEND;
3444 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003445 }
3446
Linus Torvalds1da177e2005-04-16 15:20:36 -07003447response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003448 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003449 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003450
3451sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003452 rsp.scid = cpu_to_le16(scid);
3453 rsp.dcid = cpu_to_le16(dcid);
3454 rsp.result = cpu_to_le16(result);
3455 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003456 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003457
3458 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3459 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003460 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003461
3462 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3463 conn->info_ident = l2cap_get_ident(conn);
3464
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003465 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003466
3467 l2cap_send_cmd(conn, conn->info_ident,
3468 L2CAP_INFO_REQ, sizeof(info), &info);
3469 }
3470
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003471 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003472 result == L2CAP_CR_SUCCESS) {
3473 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003474 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003475 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003476 l2cap_build_conf_req(chan, buf), buf);
3477 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003478 }
3479
Linus Torvalds1da177e2005-04-16 15:20:36 -07003480 return 0;
3481}
3482
3483static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3484{
3485 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3486 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003487 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003488 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003489 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003490
3491 scid = __le16_to_cpu(rsp->scid);
3492 dcid = __le16_to_cpu(rsp->dcid);
3493 result = __le16_to_cpu(rsp->result);
3494 status = __le16_to_cpu(rsp->status);
3495
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003496 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x",
3497 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003498
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003499 mutex_lock(&conn->chan_lock);
3500
Linus Torvalds1da177e2005-04-16 15:20:36 -07003501 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003502 chan = __l2cap_get_chan_by_scid(conn, scid);
3503 if (!chan) {
3504 err = -EFAULT;
3505 goto unlock;
3506 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003507 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003508 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3509 if (!chan) {
3510 err = -EFAULT;
3511 goto unlock;
3512 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003513 }
3514
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003515 err = 0;
3516
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003517 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003518
Linus Torvalds1da177e2005-04-16 15:20:36 -07003519 switch (result) {
3520 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003521 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003522 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003523 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003524 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003525
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003526 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003527 break;
3528
Linus Torvalds1da177e2005-04-16 15:20:36 -07003529 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003530 l2cap_build_conf_req(chan, req), req);
3531 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003532 break;
3533
3534 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003535 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003536 break;
3537
3538 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003539 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003540 break;
3541 }
3542
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003543 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003544
3545unlock:
3546 mutex_unlock(&conn->chan_lock);
3547
3548 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003549}
3550
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003551static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003552{
3553 /* FCS is enabled only in ERTM or streaming mode, if one or both
3554 * sides request it.
3555 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003556 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003557 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003558 else if (!test_bit(CONF_NO_FCS_RECV, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003559 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003560}
3561
Al Viro88219a02007-07-29 00:17:25 -07003562static 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 -07003563{
3564 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3565 u16 dcid, flags;
3566 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003567 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003568 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003569
3570 dcid = __le16_to_cpu(req->dcid);
3571 flags = __le16_to_cpu(req->flags);
3572
3573 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3574
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003575 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003576 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003577 return -ENOENT;
3578
David S. Miller033b1142011-07-21 13:38:42 -07003579 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003580 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003581
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003582 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003583 rej.scid = cpu_to_le16(chan->scid);
3584 rej.dcid = cpu_to_le16(chan->dcid);
3585
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003586 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
3587 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003588 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003589 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003590
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003591 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003592 len = cmd_len - sizeof(*req);
Dan Rosenberg7ac28812011-06-24 08:38:05 -04003593 if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003594 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003595 l2cap_build_conf_rsp(chan, rsp,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003596 L2CAP_CONF_REJECT, flags), rsp);
3597 goto unlock;
3598 }
3599
3600 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003601 memcpy(chan->conf_req + chan->conf_len, req->data, len);
3602 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003603
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003604 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003605 /* Incomplete config. Send empty response. */
3606 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003607 l2cap_build_conf_rsp(chan, rsp,
Andrei Emeltchenko5325e5b2012-05-23 11:31:22 +03003608 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003609 goto unlock;
3610 }
3611
3612 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003613 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003614 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003615 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003616 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003617 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003618
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003619 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003620 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003621
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003622 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003623 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003624
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003625 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02003626 goto unlock;
3627
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003628 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003629 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003630
Mat Martineau105bdf92012-04-27 16:50:48 -07003631 if (chan->mode == L2CAP_MODE_ERTM ||
3632 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003633 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003634
Mat Martineau3c588192012-04-11 10:48:42 -07003635 if (err < 0)
3636 l2cap_send_disconn_req(chan->conn, chan, -err);
3637 else
3638 l2cap_chan_ready(chan);
3639
Marcel Holtmann876d9482007-10-20 13:35:42 +02003640 goto unlock;
3641 }
3642
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003643 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003644 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003645 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003646 l2cap_build_conf_req(chan, buf), buf);
3647 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003648 }
3649
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003650 /* Got Conf Rsp PENDING from remote side and asume we sent
3651 Conf Rsp PENDING in the code above */
3652 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
3653 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3654
3655 /* check compatibility */
3656
3657 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3658 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3659
3660 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003661 l2cap_build_conf_rsp(chan, rsp,
Andrei Emeltchenko5325e5b2012-05-23 11:31:22 +03003662 L2CAP_CONF_SUCCESS, flags), rsp);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003663 }
3664
Linus Torvalds1da177e2005-04-16 15:20:36 -07003665unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003666 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003667 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003668}
3669
3670static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3671{
3672 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3673 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003674 struct l2cap_chan *chan;
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003675 int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07003676 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003677
3678 scid = __le16_to_cpu(rsp->scid);
3679 flags = __le16_to_cpu(rsp->flags);
3680 result = __le16_to_cpu(rsp->result);
3681
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003682 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
3683 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003684
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003685 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003686 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003687 return 0;
3688
3689 switch (result) {
3690 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003691 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003692 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003693 break;
3694
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003695 case L2CAP_CONF_PENDING:
3696 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
3697
3698 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3699 char buf[64];
3700
3701 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3702 buf, &result);
3703 if (len < 0) {
3704 l2cap_send_disconn_req(conn, chan, ECONNRESET);
3705 goto done;
3706 }
3707
3708 /* check compatibility */
3709
3710 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3711 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3712
3713 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003714 l2cap_build_conf_rsp(chan, buf,
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003715 L2CAP_CONF_SUCCESS, 0x0000), buf);
3716 }
3717 goto done;
3718
Linus Torvalds1da177e2005-04-16 15:20:36 -07003719 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003720 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003721 char req[64];
3722
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003723 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003724 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003725 goto done;
3726 }
3727
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003728 /* throw out any old stored conf requests */
3729 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003730 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3731 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003732 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003733 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003734 goto done;
3735 }
3736
3737 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3738 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003739 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003740 if (result != L2CAP_CONF_SUCCESS)
3741 goto done;
3742 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003743 }
3744
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003745 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003746 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02003747
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003748 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003749 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003750 goto done;
3751 }
3752
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003753 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003754 goto done;
3755
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003756 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003757
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003758 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003759 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003760
Mat Martineau105bdf92012-04-27 16:50:48 -07003761 if (chan->mode == L2CAP_MODE_ERTM ||
3762 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003763 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003764
Mat Martineau3c588192012-04-11 10:48:42 -07003765 if (err < 0)
3766 l2cap_send_disconn_req(chan->conn, chan, -err);
3767 else
3768 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003769 }
3770
3771done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003772 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003773 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003774}
3775
3776static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3777{
3778 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3779 struct l2cap_disconn_rsp rsp;
3780 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003781 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003782 struct sock *sk;
3783
3784 scid = __le16_to_cpu(req->scid);
3785 dcid = __le16_to_cpu(req->dcid);
3786
3787 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3788
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003789 mutex_lock(&conn->chan_lock);
3790
3791 chan = __l2cap_get_chan_by_scid(conn, dcid);
3792 if (!chan) {
3793 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003794 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003795 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003796
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003797 l2cap_chan_lock(chan);
3798
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003799 sk = chan->sk;
3800
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003801 rsp.dcid = cpu_to_le16(chan->scid);
3802 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003803 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3804
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003805 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003806 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003807 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003808
Mat Martineau61d6ef32012-04-27 16:50:50 -07003809 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003810 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003811
3812 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003813
Gustavo Padovan80b98022012-05-27 22:27:51 -03003814 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003815 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003816
3817 mutex_unlock(&conn->chan_lock);
3818
Linus Torvalds1da177e2005-04-16 15:20:36 -07003819 return 0;
3820}
3821
3822static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3823{
3824 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3825 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003826 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003827
3828 scid = __le16_to_cpu(rsp->scid);
3829 dcid = __le16_to_cpu(rsp->dcid);
3830
3831 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3832
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003833 mutex_lock(&conn->chan_lock);
3834
3835 chan = __l2cap_get_chan_by_scid(conn, scid);
3836 if (!chan) {
3837 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003838 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003839 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003840
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003841 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003842
Mat Martineau61d6ef32012-04-27 16:50:50 -07003843 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003844 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003845
3846 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003847
Gustavo Padovan80b98022012-05-27 22:27:51 -03003848 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003849 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003850
3851 mutex_unlock(&conn->chan_lock);
3852
Linus Torvalds1da177e2005-04-16 15:20:36 -07003853 return 0;
3854}
3855
3856static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3857{
3858 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003859 u16 type;
3860
3861 type = __le16_to_cpu(req->type);
3862
3863 BT_DBG("type 0x%4.4x", type);
3864
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003865 if (type == L2CAP_IT_FEAT_MASK) {
3866 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003867 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003868 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003869 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
3870 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03003871 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003872 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3873 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003874 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003875 feat_mask |= L2CAP_FEAT_EXT_FLOW
3876 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003877
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003878 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003879 l2cap_send_cmd(conn, cmd->ident,
3880 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003881 } else if (type == L2CAP_IT_FIXED_CHAN) {
3882 u8 buf[12];
3883 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07003884
3885 if (enable_hs)
3886 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
3887 else
3888 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
3889
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003890 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3891 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03003892 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003893 l2cap_send_cmd(conn, cmd->ident,
3894 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003895 } else {
3896 struct l2cap_info_rsp rsp;
3897 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003898 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003899 l2cap_send_cmd(conn, cmd->ident,
3900 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3901 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003902
3903 return 0;
3904}
3905
3906static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3907{
3908 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3909 u16 type, result;
3910
3911 type = __le16_to_cpu(rsp->type);
3912 result = __le16_to_cpu(rsp->result);
3913
3914 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3915
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02003916 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
3917 if (cmd->ident != conn->info_ident ||
3918 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
3919 return 0;
3920
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003921 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003922
Ville Tervoadb08ed2010-08-04 09:43:33 +03003923 if (result != L2CAP_IR_SUCCESS) {
3924 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3925 conn->info_ident = 0;
3926
3927 l2cap_conn_start(conn);
3928
3929 return 0;
3930 }
3931
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003932 switch (type) {
3933 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07003934 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003935
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003936 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003937 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003938 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003939
3940 conn->info_ident = l2cap_get_ident(conn);
3941
3942 l2cap_send_cmd(conn, conn->info_ident,
3943 L2CAP_INFO_REQ, sizeof(req), &req);
3944 } else {
3945 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3946 conn->info_ident = 0;
3947
3948 l2cap_conn_start(conn);
3949 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003950 break;
3951
3952 case L2CAP_IT_FIXED_CHAN:
3953 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01003954 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003955 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003956
3957 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003958 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003959 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003960
Linus Torvalds1da177e2005-04-16 15:20:36 -07003961 return 0;
3962}
3963
Mat Martineauf94ff6f2011-11-02 16:18:32 -07003964static inline int l2cap_create_channel_req(struct l2cap_conn *conn,
3965 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3966 void *data)
3967{
3968 struct l2cap_create_chan_req *req = data;
3969 struct l2cap_create_chan_rsp rsp;
3970 u16 psm, scid;
3971
3972 if (cmd_len != sizeof(*req))
3973 return -EPROTO;
3974
3975 if (!enable_hs)
3976 return -EINVAL;
3977
3978 psm = le16_to_cpu(req->psm);
3979 scid = le16_to_cpu(req->scid);
3980
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03003981 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 -07003982
3983 /* Placeholder: Always reject */
3984 rsp.dcid = 0;
3985 rsp.scid = cpu_to_le16(scid);
Andrei Emeltchenko8ce0c492012-03-12 12:13:09 +02003986 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
3987 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07003988
3989 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
3990 sizeof(rsp), &rsp);
3991
3992 return 0;
3993}
3994
3995static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn,
3996 struct l2cap_cmd_hdr *cmd, void *data)
3997{
3998 BT_DBG("conn %p", conn);
3999
4000 return l2cap_connect_rsp(conn, cmd, data);
4001}
4002
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004003static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004004 u16 icid, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004005{
4006 struct l2cap_move_chan_rsp rsp;
4007
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004008 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004009
4010 rsp.icid = cpu_to_le16(icid);
4011 rsp.result = cpu_to_le16(result);
4012
4013 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_RSP, sizeof(rsp), &rsp);
4014}
4015
4016static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004017 struct l2cap_chan *chan,
4018 u16 icid, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004019{
4020 struct l2cap_move_chan_cfm cfm;
4021 u8 ident;
4022
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004023 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004024
4025 ident = l2cap_get_ident(conn);
4026 if (chan)
4027 chan->ident = ident;
4028
4029 cfm.icid = cpu_to_le16(icid);
4030 cfm.result = cpu_to_le16(result);
4031
4032 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM, sizeof(cfm), &cfm);
4033}
4034
4035static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004036 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004037{
4038 struct l2cap_move_chan_cfm_rsp rsp;
4039
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004040 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004041
4042 rsp.icid = cpu_to_le16(icid);
4043 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4044}
4045
4046static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004047 struct l2cap_cmd_hdr *cmd,
4048 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004049{
4050 struct l2cap_move_chan_req *req = data;
4051 u16 icid = 0;
4052 u16 result = L2CAP_MR_NOT_ALLOWED;
4053
4054 if (cmd_len != sizeof(*req))
4055 return -EPROTO;
4056
4057 icid = le16_to_cpu(req->icid);
4058
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004059 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004060
4061 if (!enable_hs)
4062 return -EINVAL;
4063
4064 /* Placeholder: Always refuse */
4065 l2cap_send_move_chan_rsp(conn, cmd->ident, icid, result);
4066
4067 return 0;
4068}
4069
4070static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004071 struct l2cap_cmd_hdr *cmd,
4072 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004073{
4074 struct l2cap_move_chan_rsp *rsp = data;
4075 u16 icid, result;
4076
4077 if (cmd_len != sizeof(*rsp))
4078 return -EPROTO;
4079
4080 icid = le16_to_cpu(rsp->icid);
4081 result = le16_to_cpu(rsp->result);
4082
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004083 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004084
4085 /* Placeholder: Always unconfirmed */
4086 l2cap_send_move_chan_cfm(conn, NULL, icid, L2CAP_MC_UNCONFIRMED);
4087
4088 return 0;
4089}
4090
4091static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004092 struct l2cap_cmd_hdr *cmd,
4093 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004094{
4095 struct l2cap_move_chan_cfm *cfm = data;
4096 u16 icid, result;
4097
4098 if (cmd_len != sizeof(*cfm))
4099 return -EPROTO;
4100
4101 icid = le16_to_cpu(cfm->icid);
4102 result = le16_to_cpu(cfm->result);
4103
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004104 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004105
4106 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4107
4108 return 0;
4109}
4110
4111static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004112 struct l2cap_cmd_hdr *cmd,
4113 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004114{
4115 struct l2cap_move_chan_cfm_rsp *rsp = data;
4116 u16 icid;
4117
4118 if (cmd_len != sizeof(*rsp))
4119 return -EPROTO;
4120
4121 icid = le16_to_cpu(rsp->icid);
4122
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004123 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004124
4125 return 0;
4126}
4127
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004128static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Claudio Takahaside731152011-02-11 19:28:55 -02004129 u16 to_multiplier)
4130{
4131 u16 max_latency;
4132
4133 if (min > max || min < 6 || max > 3200)
4134 return -EINVAL;
4135
4136 if (to_multiplier < 10 || to_multiplier > 3200)
4137 return -EINVAL;
4138
4139 if (max >= to_multiplier * 8)
4140 return -EINVAL;
4141
4142 max_latency = (to_multiplier * 8 / max) - 1;
4143 if (latency > 499 || latency > max_latency)
4144 return -EINVAL;
4145
4146 return 0;
4147}
4148
4149static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
4150 struct l2cap_cmd_hdr *cmd, u8 *data)
4151{
4152 struct hci_conn *hcon = conn->hcon;
4153 struct l2cap_conn_param_update_req *req;
4154 struct l2cap_conn_param_update_rsp rsp;
4155 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004156 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02004157
4158 if (!(hcon->link_mode & HCI_LM_MASTER))
4159 return -EINVAL;
4160
4161 cmd_len = __le16_to_cpu(cmd->len);
4162 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
4163 return -EPROTO;
4164
4165 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004166 min = __le16_to_cpu(req->min);
4167 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02004168 latency = __le16_to_cpu(req->latency);
4169 to_multiplier = __le16_to_cpu(req->to_multiplier);
4170
4171 BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
4172 min, max, latency, to_multiplier);
4173
4174 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004175
4176 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
4177 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004178 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004179 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004180 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004181
4182 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
4183 sizeof(rsp), &rsp);
4184
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004185 if (!err)
4186 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
4187
Claudio Takahaside731152011-02-11 19:28:55 -02004188 return 0;
4189}
4190
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004191static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
4192 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
4193{
4194 int err = 0;
4195
4196 switch (cmd->code) {
4197 case L2CAP_COMMAND_REJ:
4198 l2cap_command_rej(conn, cmd, data);
4199 break;
4200
4201 case L2CAP_CONN_REQ:
4202 err = l2cap_connect_req(conn, cmd, data);
4203 break;
4204
4205 case L2CAP_CONN_RSP:
4206 err = l2cap_connect_rsp(conn, cmd, data);
4207 break;
4208
4209 case L2CAP_CONF_REQ:
4210 err = l2cap_config_req(conn, cmd, cmd_len, data);
4211 break;
4212
4213 case L2CAP_CONF_RSP:
4214 err = l2cap_config_rsp(conn, cmd, data);
4215 break;
4216
4217 case L2CAP_DISCONN_REQ:
4218 err = l2cap_disconnect_req(conn, cmd, data);
4219 break;
4220
4221 case L2CAP_DISCONN_RSP:
4222 err = l2cap_disconnect_rsp(conn, cmd, data);
4223 break;
4224
4225 case L2CAP_ECHO_REQ:
4226 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
4227 break;
4228
4229 case L2CAP_ECHO_RSP:
4230 break;
4231
4232 case L2CAP_INFO_REQ:
4233 err = l2cap_information_req(conn, cmd, data);
4234 break;
4235
4236 case L2CAP_INFO_RSP:
4237 err = l2cap_information_rsp(conn, cmd, data);
4238 break;
4239
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004240 case L2CAP_CREATE_CHAN_REQ:
4241 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
4242 break;
4243
4244 case L2CAP_CREATE_CHAN_RSP:
4245 err = l2cap_create_channel_rsp(conn, cmd, data);
4246 break;
4247
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004248 case L2CAP_MOVE_CHAN_REQ:
4249 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
4250 break;
4251
4252 case L2CAP_MOVE_CHAN_RSP:
4253 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
4254 break;
4255
4256 case L2CAP_MOVE_CHAN_CFM:
4257 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
4258 break;
4259
4260 case L2CAP_MOVE_CHAN_CFM_RSP:
4261 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
4262 break;
4263
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004264 default:
4265 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
4266 err = -EINVAL;
4267 break;
4268 }
4269
4270 return err;
4271}
4272
4273static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
4274 struct l2cap_cmd_hdr *cmd, u8 *data)
4275{
4276 switch (cmd->code) {
4277 case L2CAP_COMMAND_REJ:
4278 return 0;
4279
4280 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02004281 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004282
4283 case L2CAP_CONN_PARAM_UPDATE_RSP:
4284 return 0;
4285
4286 default:
4287 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
4288 return -EINVAL;
4289 }
4290}
4291
4292static inline void l2cap_sig_channel(struct l2cap_conn *conn,
4293 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004294{
4295 u8 *data = skb->data;
4296 int len = skb->len;
4297 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004298 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004299
4300 l2cap_raw_recv(conn, skb);
4301
4302 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07004303 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004304 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
4305 data += L2CAP_CMD_HDR_SIZE;
4306 len -= L2CAP_CMD_HDR_SIZE;
4307
Al Viro88219a02007-07-29 00:17:25 -07004308 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004309
Al Viro88219a02007-07-29 00:17:25 -07004310 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 -07004311
Al Viro88219a02007-07-29 00:17:25 -07004312 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004313 BT_DBG("corrupted command");
4314 break;
4315 }
4316
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004317 if (conn->hcon->type == LE_LINK)
4318 err = l2cap_le_sig_cmd(conn, &cmd, data);
4319 else
4320 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004321
4322 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004323 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03004324
4325 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004326
4327 /* FIXME: Map err to a valid reason */
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004328 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004329 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
4330 }
4331
Al Viro88219a02007-07-29 00:17:25 -07004332 data += cmd_len;
4333 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004334 }
4335
4336 kfree_skb(skb);
4337}
4338
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004339static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004340{
4341 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03004342 int hdr_size;
4343
4344 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
4345 hdr_size = L2CAP_EXT_HDR_SIZE;
4346 else
4347 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004348
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004349 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004350 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004351 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
4352 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
4353
4354 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03004355 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004356 }
4357 return 0;
4358}
4359
Mat Martineau6ea00482012-05-17 20:53:52 -07004360static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004361{
Mat Martineaue31f7632012-05-17 20:53:41 -07004362 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004363
Mat Martineaue31f7632012-05-17 20:53:41 -07004364 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004365
Mat Martineaue31f7632012-05-17 20:53:41 -07004366 memset(&control, 0, sizeof(control));
4367 control.sframe = 1;
4368 control.final = 1;
4369 control.reqseq = chan->buffer_seq;
4370 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004371
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004372 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07004373 control.super = L2CAP_SUPER_RNR;
4374 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004375 }
4376
Mat Martineaue31f7632012-05-17 20:53:41 -07004377 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
4378 chan->unacked_frames > 0)
4379 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004380
Mat Martineaue31f7632012-05-17 20:53:41 -07004381 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03004382 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004383
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004384 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07004385 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
4386 /* F-bit wasn't sent in an s-frame or i-frame yet, so
4387 * send it now.
4388 */
4389 control.super = L2CAP_SUPER_RR;
4390 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004391 }
4392}
4393
Mat Martineau84084a32011-07-22 14:54:00 -07004394static void append_skb_frag(struct sk_buff *skb,
4395 struct sk_buff *new_frag, struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004396{
Mat Martineau84084a32011-07-22 14:54:00 -07004397 /* skb->len reflects data in skb as well as all fragments
4398 * skb->data_len reflects only data in fragments
4399 */
4400 if (!skb_has_frag_list(skb))
4401 skb_shinfo(skb)->frag_list = new_frag;
4402
4403 new_frag->next = NULL;
4404
4405 (*last_frag)->next = new_frag;
4406 *last_frag = new_frag;
4407
4408 skb->len += new_frag->len;
4409 skb->data_len += new_frag->len;
4410 skb->truesize += new_frag->truesize;
4411}
4412
Mat Martineau4b51dae92012-05-17 20:53:37 -07004413static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
4414 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07004415{
4416 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004417
Mat Martineau4b51dae92012-05-17 20:53:37 -07004418 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004419 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07004420 if (chan->sdu)
4421 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004422
Gustavo Padovan80b98022012-05-27 22:27:51 -03004423 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07004424 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004425
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004426 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07004427 if (chan->sdu)
4428 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004429
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004430 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004431 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004432
Mat Martineau84084a32011-07-22 14:54:00 -07004433 if (chan->sdu_len > chan->imtu) {
4434 err = -EMSGSIZE;
4435 break;
4436 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004437
Mat Martineau84084a32011-07-22 14:54:00 -07004438 if (skb->len >= chan->sdu_len)
4439 break;
4440
4441 chan->sdu = skb;
4442 chan->sdu_last_frag = skb;
4443
4444 skb = NULL;
4445 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004446 break;
4447
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004448 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004449 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004450 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004451
Mat Martineau84084a32011-07-22 14:54:00 -07004452 append_skb_frag(chan->sdu, skb,
4453 &chan->sdu_last_frag);
4454 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004455
Mat Martineau84084a32011-07-22 14:54:00 -07004456 if (chan->sdu->len >= chan->sdu_len)
4457 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004458
Mat Martineau84084a32011-07-22 14:54:00 -07004459 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004460 break;
4461
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004462 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004463 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004464 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004465
Mat Martineau84084a32011-07-22 14:54:00 -07004466 append_skb_frag(chan->sdu, skb,
4467 &chan->sdu_last_frag);
4468 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004469
Mat Martineau84084a32011-07-22 14:54:00 -07004470 if (chan->sdu->len != chan->sdu_len)
4471 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004472
Gustavo Padovan80b98022012-05-27 22:27:51 -03004473 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004474
Mat Martineau84084a32011-07-22 14:54:00 -07004475 if (!err) {
4476 /* Reassembly complete */
4477 chan->sdu = NULL;
4478 chan->sdu_last_frag = NULL;
4479 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004480 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004481 break;
4482 }
4483
Mat Martineau84084a32011-07-22 14:54:00 -07004484 if (err) {
4485 kfree_skb(skb);
4486 kfree_skb(chan->sdu);
4487 chan->sdu = NULL;
4488 chan->sdu_last_frag = NULL;
4489 chan->sdu_len = 0;
4490 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004491
Mat Martineau84084a32011-07-22 14:54:00 -07004492 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004493}
4494
Mat Martineaue3281402011-07-07 09:39:02 -07004495void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03004496{
Mat Martineau61aa4f52012-05-17 20:53:40 -07004497 u8 event;
4498
4499 if (chan->mode != L2CAP_MODE_ERTM)
4500 return;
4501
4502 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03004503 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004504}
4505
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004506static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
4507{
Mat Martineau63838722012-05-17 20:53:45 -07004508 int err = 0;
4509 /* Pass sequential frames to l2cap_reassemble_sdu()
4510 * until a gap is encountered.
4511 */
4512
4513 BT_DBG("chan %p", chan);
4514
4515 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4516 struct sk_buff *skb;
4517 BT_DBG("Searching for skb with txseq %d (queue len %d)",
4518 chan->buffer_seq, skb_queue_len(&chan->srej_q));
4519
4520 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
4521
4522 if (!skb)
4523 break;
4524
4525 skb_unlink(skb, &chan->srej_q);
4526 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
4527 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
4528 if (err)
4529 break;
4530 }
4531
4532 if (skb_queue_empty(&chan->srej_q)) {
4533 chan->rx_state = L2CAP_RX_STATE_RECV;
4534 l2cap_send_ack(chan);
4535 }
4536
4537 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004538}
4539
4540static void l2cap_handle_srej(struct l2cap_chan *chan,
4541 struct l2cap_ctrl *control)
4542{
Mat Martineauf80842a2012-05-17 20:53:46 -07004543 struct sk_buff *skb;
4544
4545 BT_DBG("chan %p, control %p", chan, control);
4546
4547 if (control->reqseq == chan->next_tx_seq) {
4548 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4549 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4550 return;
4551 }
4552
4553 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4554
4555 if (skb == NULL) {
4556 BT_DBG("Seq %d not available for retransmission",
4557 control->reqseq);
4558 return;
4559 }
4560
4561 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
4562 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4563 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4564 return;
4565 }
4566
4567 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4568
4569 if (control->poll) {
4570 l2cap_pass_to_tx(chan, control);
4571
4572 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4573 l2cap_retransmit(chan, control);
4574 l2cap_ertm_send(chan);
4575
4576 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4577 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4578 chan->srej_save_reqseq = control->reqseq;
4579 }
4580 } else {
4581 l2cap_pass_to_tx_fbit(chan, control);
4582
4583 if (control->final) {
4584 if (chan->srej_save_reqseq != control->reqseq ||
4585 !test_and_clear_bit(CONN_SREJ_ACT,
4586 &chan->conn_state))
4587 l2cap_retransmit(chan, control);
4588 } else {
4589 l2cap_retransmit(chan, control);
4590 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4591 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4592 chan->srej_save_reqseq = control->reqseq;
4593 }
4594 }
4595 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004596}
4597
4598static void l2cap_handle_rej(struct l2cap_chan *chan,
4599 struct l2cap_ctrl *control)
4600{
Mat Martineaufcd289d2012-05-17 20:53:47 -07004601 struct sk_buff *skb;
4602
4603 BT_DBG("chan %p, control %p", chan, control);
4604
4605 if (control->reqseq == chan->next_tx_seq) {
4606 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4607 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4608 return;
4609 }
4610
4611 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4612
4613 if (chan->max_tx && skb &&
4614 bt_cb(skb)->control.retries >= chan->max_tx) {
4615 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4616 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4617 return;
4618 }
4619
4620 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4621
4622 l2cap_pass_to_tx(chan, control);
4623
4624 if (control->final) {
4625 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
4626 l2cap_retransmit_all(chan, control);
4627 } else {
4628 l2cap_retransmit_all(chan, control);
4629 l2cap_ertm_send(chan);
4630 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
4631 set_bit(CONN_REJ_ACT, &chan->conn_state);
4632 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004633}
4634
Mat Martineau4b51dae92012-05-17 20:53:37 -07004635static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
4636{
4637 BT_DBG("chan %p, txseq %d", chan, txseq);
4638
4639 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
4640 chan->expected_tx_seq);
4641
4642 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
4643 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4644 chan->tx_win) {
4645 /* See notes below regarding "double poll" and
4646 * invalid packets.
4647 */
4648 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4649 BT_DBG("Invalid/Ignore - after SREJ");
4650 return L2CAP_TXSEQ_INVALID_IGNORE;
4651 } else {
4652 BT_DBG("Invalid - in window after SREJ sent");
4653 return L2CAP_TXSEQ_INVALID;
4654 }
4655 }
4656
4657 if (chan->srej_list.head == txseq) {
4658 BT_DBG("Expected SREJ");
4659 return L2CAP_TXSEQ_EXPECTED_SREJ;
4660 }
4661
4662 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
4663 BT_DBG("Duplicate SREJ - txseq already stored");
4664 return L2CAP_TXSEQ_DUPLICATE_SREJ;
4665 }
4666
4667 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
4668 BT_DBG("Unexpected SREJ - not requested");
4669 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
4670 }
4671 }
4672
4673 if (chan->expected_tx_seq == txseq) {
4674 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4675 chan->tx_win) {
4676 BT_DBG("Invalid - txseq outside tx window");
4677 return L2CAP_TXSEQ_INVALID;
4678 } else {
4679 BT_DBG("Expected");
4680 return L2CAP_TXSEQ_EXPECTED;
4681 }
4682 }
4683
4684 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
4685 __seq_offset(chan, chan->expected_tx_seq,
4686 chan->last_acked_seq)){
4687 BT_DBG("Duplicate - expected_tx_seq later than txseq");
4688 return L2CAP_TXSEQ_DUPLICATE;
4689 }
4690
4691 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
4692 /* A source of invalid packets is a "double poll" condition,
4693 * where delays cause us to send multiple poll packets. If
4694 * the remote stack receives and processes both polls,
4695 * sequence numbers can wrap around in such a way that a
4696 * resent frame has a sequence number that looks like new data
4697 * with a sequence gap. This would trigger an erroneous SREJ
4698 * request.
4699 *
4700 * Fortunately, this is impossible with a tx window that's
4701 * less than half of the maximum sequence number, which allows
4702 * invalid frames to be safely ignored.
4703 *
4704 * With tx window sizes greater than half of the tx window
4705 * maximum, the frame is invalid and cannot be ignored. This
4706 * causes a disconnect.
4707 */
4708
4709 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4710 BT_DBG("Invalid/Ignore - txseq outside tx window");
4711 return L2CAP_TXSEQ_INVALID_IGNORE;
4712 } else {
4713 BT_DBG("Invalid - txseq outside tx window");
4714 return L2CAP_TXSEQ_INVALID;
4715 }
4716 } else {
4717 BT_DBG("Unexpected - txseq indicates missing frames");
4718 return L2CAP_TXSEQ_UNEXPECTED;
4719 }
4720}
4721
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004722static int l2cap_rx_state_recv(struct l2cap_chan *chan,
4723 struct l2cap_ctrl *control,
4724 struct sk_buff *skb, u8 event)
4725{
4726 int err = 0;
4727 bool skb_in_use = 0;
4728
4729 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4730 event);
4731
4732 switch (event) {
4733 case L2CAP_EV_RECV_IFRAME:
4734 switch (l2cap_classify_txseq(chan, control->txseq)) {
4735 case L2CAP_TXSEQ_EXPECTED:
4736 l2cap_pass_to_tx(chan, control);
4737
4738 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4739 BT_DBG("Busy, discarding expected seq %d",
4740 control->txseq);
4741 break;
4742 }
4743
4744 chan->expected_tx_seq = __next_seq(chan,
4745 control->txseq);
4746
4747 chan->buffer_seq = chan->expected_tx_seq;
4748 skb_in_use = 1;
4749
4750 err = l2cap_reassemble_sdu(chan, skb, control);
4751 if (err)
4752 break;
4753
4754 if (control->final) {
4755 if (!test_and_clear_bit(CONN_REJ_ACT,
4756 &chan->conn_state)) {
4757 control->final = 0;
4758 l2cap_retransmit_all(chan, control);
4759 l2cap_ertm_send(chan);
4760 }
4761 }
4762
4763 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
4764 l2cap_send_ack(chan);
4765 break;
4766 case L2CAP_TXSEQ_UNEXPECTED:
4767 l2cap_pass_to_tx(chan, control);
4768
4769 /* Can't issue SREJ frames in the local busy state.
4770 * Drop this frame, it will be seen as missing
4771 * when local busy is exited.
4772 */
4773 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4774 BT_DBG("Busy, discarding unexpected seq %d",
4775 control->txseq);
4776 break;
4777 }
4778
4779 /* There was a gap in the sequence, so an SREJ
4780 * must be sent for each missing frame. The
4781 * current frame is stored for later use.
4782 */
4783 skb_queue_tail(&chan->srej_q, skb);
4784 skb_in_use = 1;
4785 BT_DBG("Queued %p (queue len %d)", skb,
4786 skb_queue_len(&chan->srej_q));
4787
4788 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
4789 l2cap_seq_list_clear(&chan->srej_list);
4790 l2cap_send_srej(chan, control->txseq);
4791
4792 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
4793 break;
4794 case L2CAP_TXSEQ_DUPLICATE:
4795 l2cap_pass_to_tx(chan, control);
4796 break;
4797 case L2CAP_TXSEQ_INVALID_IGNORE:
4798 break;
4799 case L2CAP_TXSEQ_INVALID:
4800 default:
4801 l2cap_send_disconn_req(chan->conn, chan,
4802 ECONNRESET);
4803 break;
4804 }
4805 break;
4806 case L2CAP_EV_RECV_RR:
4807 l2cap_pass_to_tx(chan, control);
4808 if (control->final) {
4809 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4810
4811 if (!test_and_clear_bit(CONN_REJ_ACT,
4812 &chan->conn_state)) {
4813 control->final = 0;
4814 l2cap_retransmit_all(chan, control);
4815 }
4816
4817 l2cap_ertm_send(chan);
4818 } else if (control->poll) {
4819 l2cap_send_i_or_rr_or_rnr(chan);
4820 } else {
4821 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4822 &chan->conn_state) &&
4823 chan->unacked_frames)
4824 __set_retrans_timer(chan);
4825
4826 l2cap_ertm_send(chan);
4827 }
4828 break;
4829 case L2CAP_EV_RECV_RNR:
4830 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4831 l2cap_pass_to_tx(chan, control);
4832 if (control && control->poll) {
4833 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4834 l2cap_send_rr_or_rnr(chan, 0);
4835 }
4836 __clear_retrans_timer(chan);
4837 l2cap_seq_list_clear(&chan->retrans_list);
4838 break;
4839 case L2CAP_EV_RECV_REJ:
4840 l2cap_handle_rej(chan, control);
4841 break;
4842 case L2CAP_EV_RECV_SREJ:
4843 l2cap_handle_srej(chan, control);
4844 break;
4845 default:
4846 break;
4847 }
4848
4849 if (skb && !skb_in_use) {
4850 BT_DBG("Freeing %p", skb);
4851 kfree_skb(skb);
4852 }
4853
4854 return err;
4855}
4856
4857static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
4858 struct l2cap_ctrl *control,
4859 struct sk_buff *skb, u8 event)
4860{
4861 int err = 0;
4862 u16 txseq = control->txseq;
4863 bool skb_in_use = 0;
4864
4865 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4866 event);
4867
4868 switch (event) {
4869 case L2CAP_EV_RECV_IFRAME:
4870 switch (l2cap_classify_txseq(chan, txseq)) {
4871 case L2CAP_TXSEQ_EXPECTED:
4872 /* Keep frame for reassembly later */
4873 l2cap_pass_to_tx(chan, control);
4874 skb_queue_tail(&chan->srej_q, skb);
4875 skb_in_use = 1;
4876 BT_DBG("Queued %p (queue len %d)", skb,
4877 skb_queue_len(&chan->srej_q));
4878
4879 chan->expected_tx_seq = __next_seq(chan, txseq);
4880 break;
4881 case L2CAP_TXSEQ_EXPECTED_SREJ:
4882 l2cap_seq_list_pop(&chan->srej_list);
4883
4884 l2cap_pass_to_tx(chan, control);
4885 skb_queue_tail(&chan->srej_q, skb);
4886 skb_in_use = 1;
4887 BT_DBG("Queued %p (queue len %d)", skb,
4888 skb_queue_len(&chan->srej_q));
4889
4890 err = l2cap_rx_queued_iframes(chan);
4891 if (err)
4892 break;
4893
4894 break;
4895 case L2CAP_TXSEQ_UNEXPECTED:
4896 /* Got a frame that can't be reassembled yet.
4897 * Save it for later, and send SREJs to cover
4898 * the missing frames.
4899 */
4900 skb_queue_tail(&chan->srej_q, skb);
4901 skb_in_use = 1;
4902 BT_DBG("Queued %p (queue len %d)", skb,
4903 skb_queue_len(&chan->srej_q));
4904
4905 l2cap_pass_to_tx(chan, control);
4906 l2cap_send_srej(chan, control->txseq);
4907 break;
4908 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
4909 /* This frame was requested with an SREJ, but
4910 * some expected retransmitted frames are
4911 * missing. Request retransmission of missing
4912 * SREJ'd frames.
4913 */
4914 skb_queue_tail(&chan->srej_q, skb);
4915 skb_in_use = 1;
4916 BT_DBG("Queued %p (queue len %d)", skb,
4917 skb_queue_len(&chan->srej_q));
4918
4919 l2cap_pass_to_tx(chan, control);
4920 l2cap_send_srej_list(chan, control->txseq);
4921 break;
4922 case L2CAP_TXSEQ_DUPLICATE_SREJ:
4923 /* We've already queued this frame. Drop this copy. */
4924 l2cap_pass_to_tx(chan, control);
4925 break;
4926 case L2CAP_TXSEQ_DUPLICATE:
4927 /* Expecting a later sequence number, so this frame
4928 * was already received. Ignore it completely.
4929 */
4930 break;
4931 case L2CAP_TXSEQ_INVALID_IGNORE:
4932 break;
4933 case L2CAP_TXSEQ_INVALID:
4934 default:
4935 l2cap_send_disconn_req(chan->conn, chan,
4936 ECONNRESET);
4937 break;
4938 }
4939 break;
4940 case L2CAP_EV_RECV_RR:
4941 l2cap_pass_to_tx(chan, control);
4942 if (control->final) {
4943 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4944
4945 if (!test_and_clear_bit(CONN_REJ_ACT,
4946 &chan->conn_state)) {
4947 control->final = 0;
4948 l2cap_retransmit_all(chan, control);
4949 }
4950
4951 l2cap_ertm_send(chan);
4952 } else if (control->poll) {
4953 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4954 &chan->conn_state) &&
4955 chan->unacked_frames) {
4956 __set_retrans_timer(chan);
4957 }
4958
4959 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4960 l2cap_send_srej_tail(chan);
4961 } else {
4962 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4963 &chan->conn_state) &&
4964 chan->unacked_frames)
4965 __set_retrans_timer(chan);
4966
4967 l2cap_send_ack(chan);
4968 }
4969 break;
4970 case L2CAP_EV_RECV_RNR:
4971 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4972 l2cap_pass_to_tx(chan, control);
4973 if (control->poll) {
4974 l2cap_send_srej_tail(chan);
4975 } else {
4976 struct l2cap_ctrl rr_control;
4977 memset(&rr_control, 0, sizeof(rr_control));
4978 rr_control.sframe = 1;
4979 rr_control.super = L2CAP_SUPER_RR;
4980 rr_control.reqseq = chan->buffer_seq;
4981 l2cap_send_sframe(chan, &rr_control);
4982 }
4983
4984 break;
4985 case L2CAP_EV_RECV_REJ:
4986 l2cap_handle_rej(chan, control);
4987 break;
4988 case L2CAP_EV_RECV_SREJ:
4989 l2cap_handle_srej(chan, control);
4990 break;
4991 }
4992
4993 if (skb && !skb_in_use) {
4994 BT_DBG("Freeing %p", skb);
4995 kfree_skb(skb);
4996 }
4997
4998 return err;
4999}
5000
5001static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
5002{
5003 /* Make sure reqseq is for a packet that has been sent but not acked */
5004 u16 unacked;
5005
5006 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
5007 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
5008}
5009
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005010static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5011 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005012{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005013 int err = 0;
5014
5015 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
5016 control, skb, event, chan->rx_state);
5017
5018 if (__valid_reqseq(chan, control->reqseq)) {
5019 switch (chan->rx_state) {
5020 case L2CAP_RX_STATE_RECV:
5021 err = l2cap_rx_state_recv(chan, control, skb, event);
5022 break;
5023 case L2CAP_RX_STATE_SREJ_SENT:
5024 err = l2cap_rx_state_srej_sent(chan, control, skb,
5025 event);
5026 break;
5027 default:
5028 /* shut it down */
5029 break;
5030 }
5031 } else {
5032 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
5033 control->reqseq, chan->next_tx_seq,
5034 chan->expected_ack_seq);
5035 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
5036 }
5037
5038 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005039}
5040
5041static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5042 struct sk_buff *skb)
5043{
Mat Martineau4b51dae92012-05-17 20:53:37 -07005044 int err = 0;
5045
5046 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
5047 chan->rx_state);
5048
5049 if (l2cap_classify_txseq(chan, control->txseq) ==
5050 L2CAP_TXSEQ_EXPECTED) {
5051 l2cap_pass_to_tx(chan, control);
5052
5053 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
5054 __next_seq(chan, chan->buffer_seq));
5055
5056 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5057
5058 l2cap_reassemble_sdu(chan, skb, control);
5059 } else {
5060 if (chan->sdu) {
5061 kfree_skb(chan->sdu);
5062 chan->sdu = NULL;
5063 }
5064 chan->sdu_last_frag = NULL;
5065 chan->sdu_len = 0;
5066
5067 if (skb) {
5068 BT_DBG("Freeing %p", skb);
5069 kfree_skb(skb);
5070 }
5071 }
5072
5073 chan->last_acked_seq = control->txseq;
5074 chan->expected_tx_seq = __next_seq(chan, control->txseq);
5075
5076 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005077}
5078
5079static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
5080{
5081 struct l2cap_ctrl *control = &bt_cb(skb)->control;
5082 u16 len;
5083 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005084
Mat Martineaub76bbd62012-04-11 10:48:43 -07005085 __unpack_control(chan, skb);
5086
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005087 len = skb->len;
5088
5089 /*
5090 * We can just drop the corrupted I-frame here.
5091 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005092 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005093 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005094 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005095 goto drop;
5096
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005097 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005098 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005099
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005100 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005101 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005102
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005103 if (len > chan->mps) {
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005104 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005105 goto drop;
5106 }
5107
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005108 if (!control->sframe) {
5109 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005110
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005111 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
5112 control->sar, control->reqseq, control->final,
5113 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03005114
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005115 /* Validate F-bit - F=0 always valid, F=1 only
5116 * valid in TX WAIT_F
5117 */
5118 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005119 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005120
5121 if (chan->mode != L2CAP_MODE_STREAMING) {
5122 event = L2CAP_EV_RECV_IFRAME;
5123 err = l2cap_rx(chan, control, skb, event);
5124 } else {
5125 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005126 }
5127
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005128 if (err)
5129 l2cap_send_disconn_req(chan->conn, chan,
5130 ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005131 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005132 const u8 rx_func_to_event[4] = {
5133 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
5134 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
5135 };
5136
5137 /* Only I-frames are expected in streaming mode */
5138 if (chan->mode == L2CAP_MODE_STREAMING)
5139 goto drop;
5140
5141 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
5142 control->reqseq, control->final, control->poll,
5143 control->super);
5144
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005145 if (len != 0) {
5146 BT_ERR("%d", len);
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005147 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005148 goto drop;
5149 }
5150
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005151 /* Validate F and P bits */
5152 if (control->final && (control->poll ||
5153 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
5154 goto drop;
5155
5156 event = rx_func_to_event[control->super];
5157 if (l2cap_rx(chan, control, skb, event))
5158 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005159 }
5160
5161 return 0;
5162
5163drop:
5164 kfree_skb(skb);
5165 return 0;
5166}
5167
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005168static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
5169 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005170{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005171 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005172
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03005173 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005174 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005175 if (cid == L2CAP_CID_A2MP) {
5176 chan = a2mp_channel_create(conn, skb);
5177 if (!chan) {
5178 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005179 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005180 }
5181
5182 l2cap_chan_lock(chan);
5183 } else {
5184 BT_DBG("unknown cid 0x%4.4x", cid);
5185 /* Drop packet and return */
5186 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005187 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005188 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005189 }
5190
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03005191 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005192
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005193 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005194 goto drop;
5195
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005196 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005197 case L2CAP_MODE_BASIC:
5198 /* If socket recv buffers overflows we drop data here
5199 * which is *bad* because L2CAP has to be reliable.
5200 * But we don't have any other choice. L2CAP doesn't
5201 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005202
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005203 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005204 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005205
Gustavo Padovan80b98022012-05-27 22:27:51 -03005206 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005207 goto done;
5208 break;
5209
5210 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005211 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005212 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005213 goto done;
5214
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005215 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005216 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005217 break;
5218 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005219
5220drop:
5221 kfree_skb(skb);
5222
5223done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005224 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005225}
5226
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03005227static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
5228 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005229{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005230 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005231
Ido Yarivc2287682012-04-20 15:46:07 -03005232 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005233 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005234 goto drop;
5235
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005236 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005237
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005238 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005239 goto drop;
5240
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005241 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005242 goto drop;
5243
Gustavo Padovan80b98022012-05-27 22:27:51 -03005244 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03005245 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005246
5247drop:
5248 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005249}
5250
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03005251static void l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
5252 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005253{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005254 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005255
Ido Yarivc2287682012-04-20 15:46:07 -03005256 chan = l2cap_global_chan_by_scid(0, cid, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005257 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005258 goto drop;
5259
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005260 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005261
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005262 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005263 goto drop;
5264
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005265 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005266 goto drop;
5267
Gustavo Padovan80b98022012-05-27 22:27:51 -03005268 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03005269 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005270
5271drop:
5272 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005273}
5274
Linus Torvalds1da177e2005-04-16 15:20:36 -07005275static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
5276{
5277 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07005278 u16 cid, len;
5279 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005280
5281 skb_pull(skb, L2CAP_HDR_SIZE);
5282 cid = __le16_to_cpu(lh->cid);
5283 len = __le16_to_cpu(lh->len);
5284
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005285 if (len != skb->len) {
5286 kfree_skb(skb);
5287 return;
5288 }
5289
Linus Torvalds1da177e2005-04-16 15:20:36 -07005290 BT_DBG("len %d, cid 0x%4.4x", len, cid);
5291
5292 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005293 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005294 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005295 l2cap_sig_channel(conn, skb);
5296 break;
5297
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005298 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02005299 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03005300 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005301 l2cap_conless_channel(conn, psm, skb);
5302 break;
5303
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005304 case L2CAP_CID_LE_DATA:
5305 l2cap_att_channel(conn, cid, skb);
5306 break;
5307
Anderson Brigliab501d6a2011-06-07 18:46:31 -03005308 case L2CAP_CID_SMP:
5309 if (smp_sig_channel(conn, skb))
5310 l2cap_conn_del(conn->hcon, EACCES);
5311 break;
5312
Linus Torvalds1da177e2005-04-16 15:20:36 -07005313 default:
5314 l2cap_data_channel(conn, cid, skb);
5315 break;
5316 }
5317}
5318
5319/* ---- L2CAP interface with lower layer (HCI) ---- */
5320
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005321int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005322{
5323 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005324 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005325
Linus Torvalds1da177e2005-04-16 15:20:36 -07005326 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
5327
5328 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005329 read_lock(&chan_list_lock);
5330 list_for_each_entry(c, &chan_list, global_l) {
5331 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005332
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005333 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005334 continue;
5335
5336 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005337 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005338 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005339 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005340 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005341 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
5342 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005343 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005344 lm2 |= HCI_LM_MASTER;
5345 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005346 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005347 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005348
5349 return exact ? lm1 : lm2;
5350}
5351
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03005352void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005353{
Marcel Holtmann01394182006-07-03 10:02:46 +02005354 struct l2cap_conn *conn;
5355
Linus Torvalds1da177e2005-04-16 15:20:36 -07005356 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
5357
Linus Torvalds1da177e2005-04-16 15:20:36 -07005358 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005359 conn = l2cap_conn_add(hcon, status);
5360 if (conn)
5361 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02005362 } else
Joe Perchese1750722011-06-29 18:18:29 -07005363 l2cap_conn_del(hcon, bt_to_errno(status));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005364
Linus Torvalds1da177e2005-04-16 15:20:36 -07005365}
5366
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005367int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01005368{
5369 struct l2cap_conn *conn = hcon->l2cap_data;
5370
5371 BT_DBG("hcon %p", hcon);
5372
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005373 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02005374 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01005375 return conn->disc_reason;
5376}
5377
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03005378void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005379{
5380 BT_DBG("hcon %p reason %d", hcon, reason);
5381
Joe Perchese1750722011-06-29 18:18:29 -07005382 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005383}
5384
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005385static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005386{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03005387 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01005388 return;
5389
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005390 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005391 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005392 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005393 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03005394 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005395 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005396 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03005397 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005398 }
5399}
5400
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005401int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005402{
Marcel Holtmann40be4922008-07-14 20:13:50 +02005403 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005404 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005405
Marcel Holtmann01394182006-07-03 10:02:46 +02005406 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005407 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02005408
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03005409 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005410
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005411 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05305412 if (!status && encrypt)
5413 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02005414 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005415 }
5416
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005417 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005418
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005419 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005420 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005421
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03005422 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
5423 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005424
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03005425 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
5426 l2cap_chan_unlock(chan);
5427 continue;
5428 }
5429
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005430 if (chan->scid == L2CAP_CID_LE_DATA) {
5431 if (!status && encrypt) {
5432 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02005433 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005434 }
5435
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005436 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005437 continue;
5438 }
5439
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03005440 if (test_bit(CONF_CONNECT_PEND, &chan->conf_state)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005441 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01005442 continue;
5443 }
5444
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005445 if (!status && (chan->state == BT_CONNECTED ||
5446 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03005447 struct sock *sk = chan->sk;
5448
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005449 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03005450 sk->sk_state_change(sk);
5451
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005452 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005453 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02005454 continue;
5455 }
5456
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005457 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005458 if (!status) {
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02005459 l2cap_send_conn_req(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005460 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005461 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005462 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005463 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005464 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005465 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005466 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005467
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005468 lock_sock(sk);
5469
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005470 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005471 if (test_bit(BT_SK_DEFER_SETUP,
5472 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005473 struct sock *parent = bt_sk(sk)->parent;
5474 res = L2CAP_CR_PEND;
5475 stat = L2CAP_CS_AUTHOR_PEND;
Ilia Kolomisnky05e9a2f2011-07-15 18:30:21 +00005476 if (parent)
5477 parent->sk_data_ready(parent, 0);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005478 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005479 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005480 res = L2CAP_CR_SUCCESS;
5481 stat = L2CAP_CS_NO_INFO;
5482 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005483 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005484 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005485 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005486 res = L2CAP_CR_SEC_BLOCK;
5487 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005488 }
5489
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005490 release_sock(sk);
5491
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03005492 rsp.scid = cpu_to_le16(chan->dcid);
5493 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005494 rsp.result = cpu_to_le16(res);
5495 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03005496 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
5497 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07005498
5499 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
5500 res == L2CAP_CR_SUCCESS) {
5501 char buf[128];
5502 set_bit(CONF_REQ_SENT, &chan->conf_state);
5503 l2cap_send_cmd(conn, l2cap_get_ident(conn),
5504 L2CAP_CONF_REQ,
5505 l2cap_build_conf_req(chan, buf),
5506 buf);
5507 chan->num_conf_req++;
5508 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005509 }
5510
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005511 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005512 }
5513
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005514 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005515
Linus Torvalds1da177e2005-04-16 15:20:36 -07005516 return 0;
5517}
5518
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005519int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005520{
5521 struct l2cap_conn *conn = hcon->l2cap_data;
5522
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02005523 if (!conn)
5524 conn = l2cap_conn_add(hcon, 0);
5525
5526 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005527 goto drop;
5528
5529 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
5530
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +02005531 if (!(flags & ACL_CONT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005532 struct l2cap_hdr *hdr;
5533 int len;
5534
5535 if (conn->rx_len) {
5536 BT_ERR("Unexpected start frame (len %d)", skb->len);
5537 kfree_skb(conn->rx_skb);
5538 conn->rx_skb = NULL;
5539 conn->rx_len = 0;
5540 l2cap_conn_unreliable(conn, ECOMM);
5541 }
5542
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03005543 /* Start fragment always begin with Basic L2CAP header */
5544 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005545 BT_ERR("Frame is too short (len %d)", skb->len);
5546 l2cap_conn_unreliable(conn, ECOMM);
5547 goto drop;
5548 }
5549
5550 hdr = (struct l2cap_hdr *) skb->data;
5551 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
5552
5553 if (len == skb->len) {
5554 /* Complete frame received */
5555 l2cap_recv_frame(conn, skb);
5556 return 0;
5557 }
5558
5559 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
5560
5561 if (skb->len > len) {
5562 BT_ERR("Frame is too long (len %d, expected len %d)",
5563 skb->len, len);
5564 l2cap_conn_unreliable(conn, ECOMM);
5565 goto drop;
5566 }
5567
5568 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03005569 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
5570 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005571 goto drop;
5572
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005573 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01005574 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005575 conn->rx_len = len - skb->len;
5576 } else {
5577 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
5578
5579 if (!conn->rx_len) {
5580 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
5581 l2cap_conn_unreliable(conn, ECOMM);
5582 goto drop;
5583 }
5584
5585 if (skb->len > conn->rx_len) {
5586 BT_ERR("Fragment is too long (len %d, expected %d)",
5587 skb->len, conn->rx_len);
5588 kfree_skb(conn->rx_skb);
5589 conn->rx_skb = NULL;
5590 conn->rx_len = 0;
5591 l2cap_conn_unreliable(conn, ECOMM);
5592 goto drop;
5593 }
5594
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005595 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01005596 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005597 conn->rx_len -= skb->len;
5598
5599 if (!conn->rx_len) {
5600 /* Complete frame received */
5601 l2cap_recv_frame(conn, conn->rx_skb);
5602 conn->rx_skb = NULL;
5603 }
5604 }
5605
5606drop:
5607 kfree_skb(skb);
5608 return 0;
5609}
5610
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005611static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005612{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005613 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005614
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005615 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005616
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005617 list_for_each_entry(c, &chan_list, global_l) {
5618 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005619
Gustavo F. Padovan903d3432011-02-10 14:16:06 -02005620 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 +01005621 batostr(&bt_sk(sk)->src),
5622 batostr(&bt_sk(sk)->dst),
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005623 c->state, __le16_to_cpu(c->psm),
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005624 c->scid, c->dcid, c->imtu, c->omtu,
5625 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02005626 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005627
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005628 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005629
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005630 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005631}
5632
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005633static int l2cap_debugfs_open(struct inode *inode, struct file *file)
5634{
5635 return single_open(file, l2cap_debugfs_show, inode->i_private);
5636}
5637
5638static const struct file_operations l2cap_debugfs_fops = {
5639 .open = l2cap_debugfs_open,
5640 .read = seq_read,
5641 .llseek = seq_lseek,
5642 .release = single_release,
5643};
5644
5645static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005646
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005647int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005648{
5649 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005650
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005651 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005652 if (err < 0)
5653 return err;
5654
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005655 if (bt_debugfs) {
5656 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
5657 bt_debugfs, NULL, &l2cap_debugfs_fops);
5658 if (!l2cap_debugfs)
5659 BT_ERR("Failed to create L2CAP debug file");
5660 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005661
Linus Torvalds1da177e2005-04-16 15:20:36 -07005662 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005663}
5664
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005665void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005666{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005667 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005668 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005669}
5670
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03005671module_param(disable_ertm, bool, 0644);
5672MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");