blob: 65c3f4e13965a1615177929fca147da63e4339da [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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070040
Mat Martineaud1de6d42012-05-17 20:53:55 -070041bool disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020042
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070043static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Mat Martineau50a147c2011-11-02 16:18:34 -070044static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070045
Johannes Bergb5ad8b72011-06-01 08:54:45 +020046static LIST_HEAD(chan_list);
47static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
Linus Torvalds1da177e2005-04-16 15:20:36 -070049static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
50 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030051static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
52 void *data);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -030053static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030054static void l2cap_send_disconn_req(struct l2cap_conn *conn,
Gustavo Padovanc5daa682012-05-16 12:17:10 -030055 struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070056
Gustavo Padovand6603662012-05-21 13:58:22 -030057static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
Mat Martineau608bcc62012-05-17 20:53:32 -070058 struct sk_buff_head *skbs, u8 event);
59
Marcel Holtmann01394182006-07-03 10:02:46 +020060/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030061
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030062static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020063{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020064 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030065
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020066 list_for_each_entry(c, &conn->chan_l, list) {
67 if (c->dcid == cid)
68 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020069 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020070 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020071}
72
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030073static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020074{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020075 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030076
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020077 list_for_each_entry(c, &conn->chan_l, list) {
78 if (c->scid == cid)
79 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020080 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020081 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020082}
83
84/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -070085 * Returns locked channel. */
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030086static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020087{
Gustavo F. Padovan48454072011-03-25 00:22:30 -030088 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030089
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020090 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030091 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -070092 if (c)
93 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020094 mutex_unlock(&conn->chan_lock);
95
Gustavo F. Padovan48454072011-03-25 00:22:30 -030096 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020097}
98
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030099static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200100{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200101 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300102
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200103 list_for_each_entry(c, &conn->chan_l, list) {
104 if (c->ident == ident)
105 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200106 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200107 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200108}
109
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300110static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300111{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300112 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300113
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300114 list_for_each_entry(c, &chan_list, global_l) {
115 if (c->sport == psm && !bacmp(&bt_sk(c->sk)->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100116 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300117 }
Szymon Janc250938c2011-11-16 09:32:22 +0100118 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300119}
120
121int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
122{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300123 int err;
124
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200125 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300126
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300127 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300128 err = -EADDRINUSE;
129 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300130 }
131
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300132 if (psm) {
133 chan->psm = psm;
134 chan->sport = psm;
135 err = 0;
136 } else {
137 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300138
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300139 err = -EINVAL;
140 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300141 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300142 chan->psm = cpu_to_le16(p);
143 chan->sport = cpu_to_le16(p);
144 err = 0;
145 break;
146 }
147 }
148
149done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200150 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300151 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300152}
153
154int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
155{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200156 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300157
158 chan->scid = scid;
159
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200160 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300161
162 return 0;
163}
164
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300165static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200166{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300167 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200168
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300169 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300170 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200171 return cid;
172 }
173
174 return 0;
175}
176
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200177static void __l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300178{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200179 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200180 state_to_string(state));
181
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300182 chan->state = state;
183 chan->ops->state_change(chan->data, state);
184}
185
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200186static void l2cap_state_change(struct l2cap_chan *chan, int state)
187{
188 struct sock *sk = chan->sk;
189
190 lock_sock(sk);
191 __l2cap_state_change(chan, state);
192 release_sock(sk);
193}
194
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200195static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err)
196{
197 struct sock *sk = chan->sk;
198
199 sk->sk_err = err;
200}
201
202static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
203{
204 struct sock *sk = chan->sk;
205
206 lock_sock(sk);
207 __l2cap_chan_set_err(chan, err);
208 release_sock(sk);
209}
210
Mat Martineau4239d162012-05-17 20:53:49 -0700211static void __set_retrans_timer(struct l2cap_chan *chan)
212{
213 if (!delayed_work_pending(&chan->monitor_timer) &&
214 chan->retrans_timeout) {
215 l2cap_set_timer(chan, &chan->retrans_timer,
216 msecs_to_jiffies(chan->retrans_timeout));
217 }
218}
219
220static void __set_monitor_timer(struct l2cap_chan *chan)
221{
222 __clear_retrans_timer(chan);
223 if (chan->monitor_timeout) {
224 l2cap_set_timer(chan, &chan->monitor_timer,
225 msecs_to_jiffies(chan->monitor_timeout));
226 }
227}
228
Mat Martineau608bcc62012-05-17 20:53:32 -0700229static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
230 u16 seq)
231{
232 struct sk_buff *skb;
233
234 skb_queue_walk(head, skb) {
235 if (bt_cb(skb)->control.txseq == seq)
236 return skb;
237 }
238
239 return NULL;
240}
241
Mat Martineau3c588192012-04-11 10:48:42 -0700242/* ---- L2CAP sequence number lists ---- */
243
244/* For ERTM, ordered lists of sequence numbers must be tracked for
245 * SREJ requests that are received and for frames that are to be
246 * retransmitted. These seq_list functions implement a singly-linked
247 * list in an array, where membership in the list can also be checked
248 * in constant time. Items can also be added to the tail of the list
249 * and removed from the head in constant time, without further memory
250 * allocs or frees.
251 */
252
253static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
254{
255 size_t alloc_size, i;
256
257 /* Allocated size is a power of 2 to map sequence numbers
258 * (which may be up to 14 bits) in to a smaller array that is
259 * sized for the negotiated ERTM transmit windows.
260 */
261 alloc_size = roundup_pow_of_two(size);
262
263 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
264 if (!seq_list->list)
265 return -ENOMEM;
266
267 seq_list->mask = alloc_size - 1;
268 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
269 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
270 for (i = 0; i < alloc_size; i++)
271 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
272
273 return 0;
274}
275
276static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
277{
278 kfree(seq_list->list);
279}
280
281static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
282 u16 seq)
283{
284 /* Constant-time check for list membership */
285 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
286}
287
288static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
289{
290 u16 mask = seq_list->mask;
291
292 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
293 /* In case someone tries to pop the head of an empty list */
294 return L2CAP_SEQ_LIST_CLEAR;
295 } else if (seq_list->head == seq) {
296 /* Head can be removed in constant time */
297 seq_list->head = seq_list->list[seq & mask];
298 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
299
300 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
301 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
302 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
303 }
304 } else {
305 /* Walk the list to find the sequence number */
306 u16 prev = seq_list->head;
307 while (seq_list->list[prev & mask] != seq) {
308 prev = seq_list->list[prev & mask];
309 if (prev == L2CAP_SEQ_LIST_TAIL)
310 return L2CAP_SEQ_LIST_CLEAR;
311 }
312
313 /* Unlink the number from the list and clear it */
314 seq_list->list[prev & mask] = seq_list->list[seq & mask];
315 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
316 if (seq_list->tail == seq)
317 seq_list->tail = prev;
318 }
319 return seq;
320}
321
322static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
323{
324 /* Remove the head in constant time */
325 return l2cap_seq_list_remove(seq_list, seq_list->head);
326}
327
328static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
329{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300330 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700331
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300332 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
333 return;
334
335 for (i = 0; i <= seq_list->mask; i++)
336 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
337
338 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
339 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700340}
341
342static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
343{
344 u16 mask = seq_list->mask;
345
346 /* All appends happen in constant time */
347
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300348 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
349 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700350
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300351 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
352 seq_list->head = seq;
353 else
354 seq_list->list[seq_list->tail & mask] = seq;
355
356 seq_list->tail = seq;
357 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700358}
359
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300360static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300361{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300362 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
363 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200364 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300365 int reason;
366
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200367 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300368
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200369 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200370 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300371
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300372 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300373 reason = ECONNREFUSED;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300374 else if (chan->state == BT_CONNECT &&
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300375 chan->sec_level != BT_SECURITY_SDP)
376 reason = ECONNREFUSED;
377 else
378 reason = ETIMEDOUT;
379
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300380 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300381
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200382 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300383
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -0300384 chan->ops->close(chan->data);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200385 mutex_unlock(&conn->chan_lock);
386
Ulisses Furquim371fd832011-12-21 20:02:36 -0200387 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300388}
389
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300390struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200391{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300392 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200393
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300394 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
395 if (!chan)
396 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200397
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200398 mutex_init(&chan->lock);
399
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200400 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300401 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200402 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300403
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300404 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300405
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300406 chan->state = BT_OPEN;
407
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300408 atomic_set(&chan->refcnt, 1);
409
Mat Martineau28270112012-05-17 21:14:09 -0700410 /* This flag is cleared in l2cap_chan_ready() */
411 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
412
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300413 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100414
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300415 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200416}
417
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300418void l2cap_chan_destroy(struct l2cap_chan *chan)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300419{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200420 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300421 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200422 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300423
Ulisses Furquim371fd832011-12-21 20:02:36 -0200424 l2cap_chan_put(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300425}
426
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300427void l2cap_chan_set_defaults(struct l2cap_chan *chan)
428{
429 chan->fcs = L2CAP_FCS_CRC16;
430 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
431 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
432 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
433 chan->sec_level = BT_SECURITY_LOW;
434
435 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
436}
437
Andrei Emeltchenko14a28492012-03-23 16:31:49 +0200438static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200439{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300440 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200441 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200442
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200443 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100444
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300445 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200446
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200447 switch (chan->chan_type) {
448 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300449 if (conn->hcon->type == LE_LINK) {
450 /* LE connection */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300451 chan->omtu = L2CAP_LE_DEFAULT_MTU;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300452 chan->scid = L2CAP_CID_LE_DATA;
453 chan->dcid = L2CAP_CID_LE_DATA;
Ville Tervob62f3282011-02-10 22:38:50 -0300454 } else {
455 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300456 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300457 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300458 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200459 break;
460
461 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200462 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300463 chan->scid = L2CAP_CID_CONN_LESS;
464 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300465 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200466 break;
467
468 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200469 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300470 chan->scid = L2CAP_CID_SIGNALING;
471 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300472 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200473 }
474
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300475 chan->local_id = L2CAP_BESTEFFORT_ID;
476 chan->local_stype = L2CAP_SERV_BESTEFFORT;
477 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
478 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
479 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
480 chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO;
481
Ulisses Furquim371fd832011-12-21 20:02:36 -0200482 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300483
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200484 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200485}
486
Andrei Emeltchenko14a28492012-03-23 16:31:49 +0200487static void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200488{
489 mutex_lock(&conn->chan_lock);
490 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200491 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200492}
493
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300494static void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200495{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300496 struct sock *sk = chan->sk;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300497 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200498 struct sock *parent = bt_sk(sk)->parent;
499
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300500 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200501
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300502 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200503
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900504 if (conn) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300505 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200506 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200507
Ulisses Furquim371fd832011-12-21 20:02:36 -0200508 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300509
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300510 chan->conn = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200511 hci_conn_put(conn->hcon);
512 }
513
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200514 lock_sock(sk);
515
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200516 __l2cap_state_change(chan, BT_CLOSED);
Marcel Holtmann01394182006-07-03 10:02:46 +0200517 sock_set_flag(sk, SOCK_ZAPPED);
518
519 if (err)
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200520 __l2cap_chan_set_err(chan, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200521
522 if (parent) {
523 bt_accept_unlink(sk);
524 parent->sk_data_ready(parent, 0);
525 } else
526 sk->sk_state_change(sk);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300527
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200528 release_sock(sk);
529
Mat Martineau28270112012-05-17 21:14:09 -0700530 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300531 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300532
Gustavo Padovanee556f62012-05-18 20:22:38 -0300533 switch(chan->mode) {
534 case L2CAP_MODE_BASIC:
535 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300536
Gustavo Padovanee556f62012-05-18 20:22:38 -0300537 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300538 __clear_retrans_timer(chan);
539 __clear_monitor_timer(chan);
540 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300541
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300542 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300543
Mat Martineau3c588192012-04-11 10:48:42 -0700544 l2cap_seq_list_free(&chan->srej_list);
545 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300546
547 /* fall through */
548
549 case L2CAP_MODE_STREAMING:
550 skb_queue_purge(&chan->tx_q);
551 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300552 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300553
554 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200555}
556
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300557static void l2cap_chan_cleanup_listen(struct sock *parent)
558{
559 struct sock *sk;
560
561 BT_DBG("parent %p", parent);
562
563 /* Close not yet accepted channels */
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300564 while ((sk = bt_accept_dequeue(parent, NULL))) {
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -0300565 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200566
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200567 l2cap_chan_lock(chan);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300568 __clear_chan_timer(chan);
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -0300569 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200570 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200571
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -0300572 chan->ops->close(chan->data);
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300573 }
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300574}
575
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300576void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300577{
578 struct l2cap_conn *conn = chan->conn;
579 struct sock *sk = chan->sk;
580
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200581 BT_DBG("chan %p state %s sk %p", chan,
582 state_to_string(chan->state), sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300583
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300584 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300585 case BT_LISTEN:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200586 lock_sock(sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300587 l2cap_chan_cleanup_listen(sk);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300588
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200589 __l2cap_state_change(chan, BT_CLOSED);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300590 sock_set_flag(sk, SOCK_ZAPPED);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200591 release_sock(sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300592 break;
593
594 case BT_CONNECTED:
595 case BT_CONFIG:
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) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300598 __set_chan_timer(chan, sk->sk_sndtimeo);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300599 l2cap_send_disconn_req(conn, chan, reason);
600 } else
601 l2cap_chan_del(chan, reason);
602 break;
603
604 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300605 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300606 conn->hcon->type == ACL_LINK) {
607 struct l2cap_conn_rsp rsp;
608 __u16 result;
609
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300610 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300611 result = L2CAP_CR_SEC_BLOCK;
612 else
613 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300614 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300615
616 rsp.scid = cpu_to_le16(chan->dcid);
617 rsp.dcid = cpu_to_le16(chan->scid);
618 rsp.result = cpu_to_le16(result);
619 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
620 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
621 sizeof(rsp), &rsp);
622 }
623
624 l2cap_chan_del(chan, reason);
625 break;
626
627 case BT_CONNECT:
628 case BT_DISCONN:
629 l2cap_chan_del(chan, reason);
630 break;
631
632 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200633 lock_sock(sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300634 sock_set_flag(sk, SOCK_ZAPPED);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200635 release_sock(sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300636 break;
637 }
638}
639
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300640static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530641{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300642 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300643 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530644 case BT_SECURITY_HIGH:
645 return HCI_AT_DEDICATED_BONDING_MITM;
646 case BT_SECURITY_MEDIUM:
647 return HCI_AT_DEDICATED_BONDING;
648 default:
649 return HCI_AT_NO_BONDING;
650 }
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +0300651 } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300652 if (chan->sec_level == BT_SECURITY_LOW)
653 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530654
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300655 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530656 return HCI_AT_NO_BONDING_MITM;
657 else
658 return HCI_AT_NO_BONDING;
659 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300660 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530661 case BT_SECURITY_HIGH:
662 return HCI_AT_GENERAL_BONDING_MITM;
663 case BT_SECURITY_MEDIUM:
664 return HCI_AT_GENERAL_BONDING;
665 default:
666 return HCI_AT_NO_BONDING;
667 }
668 }
669}
670
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200671/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200672int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200673{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300674 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100675 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200676
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300677 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100678
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300679 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200680}
681
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200682static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200683{
684 u8 id;
685
686 /* Get next available identificator.
687 * 1 - 128 are used by kernel.
688 * 129 - 199 are reserved.
689 * 200 - 254 are used by utilities like l2ping, etc.
690 */
691
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200692 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200693
694 if (++conn->tx_ident > 128)
695 conn->tx_ident = 1;
696
697 id = conn->tx_ident;
698
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200699 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200700
701 return id;
702}
703
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300704static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200705{
706 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200707 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200708
709 BT_DBG("code 0x%2.2x", code);
710
711 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300712 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200713
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200714 if (lmp_no_flush_capable(conn->hcon->hdev))
715 flags = ACL_START_NO_FLUSH;
716 else
717 flags = ACL_START;
718
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700719 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200720 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700721
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200722 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200723}
724
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200725static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
726{
727 struct hci_conn *hcon = chan->conn->hcon;
728 u16 flags;
729
730 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
731 skb->priority);
732
733 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
734 lmp_no_flush_capable(hcon->hdev))
735 flags = ACL_START_NO_FLUSH;
736 else
737 flags = ACL_START;
738
739 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
740 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741}
742
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700743static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
744{
745 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
746 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
747
748 if (enh & L2CAP_CTRL_FRAME_TYPE) {
749 /* S-Frame */
750 control->sframe = 1;
751 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
752 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
753
754 control->sar = 0;
755 control->txseq = 0;
756 } else {
757 /* I-Frame */
758 control->sframe = 0;
759 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
760 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
761
762 control->poll = 0;
763 control->super = 0;
764 }
765}
766
767static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
768{
769 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
770 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
771
772 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
773 /* S-Frame */
774 control->sframe = 1;
775 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
776 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
777
778 control->sar = 0;
779 control->txseq = 0;
780 } else {
781 /* I-Frame */
782 control->sframe = 0;
783 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
784 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
785
786 control->poll = 0;
787 control->super = 0;
788 }
789}
790
791static inline void __unpack_control(struct l2cap_chan *chan,
792 struct sk_buff *skb)
793{
794 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
795 __unpack_extended_control(get_unaligned_le32(skb->data),
796 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700797 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700798 } else {
799 __unpack_enhanced_control(get_unaligned_le16(skb->data),
800 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700801 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700802 }
803}
804
805static u32 __pack_extended_control(struct l2cap_ctrl *control)
806{
807 u32 packed;
808
809 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
810 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
811
812 if (control->sframe) {
813 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
814 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
815 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
816 } else {
817 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
818 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
819 }
820
821 return packed;
822}
823
824static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
825{
826 u16 packed;
827
828 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
829 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
830
831 if (control->sframe) {
832 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
833 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
834 packed |= L2CAP_CTRL_FRAME_TYPE;
835 } else {
836 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
837 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
838 }
839
840 return packed;
841}
842
843static inline void __pack_control(struct l2cap_chan *chan,
844 struct l2cap_ctrl *control,
845 struct sk_buff *skb)
846{
847 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
848 put_unaligned_le32(__pack_extended_control(control),
849 skb->data + L2CAP_HDR_SIZE);
850 } else {
851 put_unaligned_le16(__pack_enhanced_control(control),
852 skb->data + L2CAP_HDR_SIZE);
853 }
854}
855
Mat Martineaua67d7f62012-05-17 20:53:35 -0700856static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
857 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300858{
859 struct sk_buff *skb;
860 struct l2cap_hdr *lh;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700861 int hlen;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300862
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +0300863 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
864 hlen = L2CAP_EXT_HDR_SIZE;
865 else
866 hlen = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300867
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300868 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300869 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300870
Mat Martineaua67d7f62012-05-17 20:53:35 -0700871 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300872
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300873 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700874 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300875
876 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300877 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300878 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300879
Mat Martineaua67d7f62012-05-17 20:53:35 -0700880 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
881 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
882 else
883 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300884
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300885 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700886 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300887 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300888 }
889
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200890 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700891 return skb;
892}
893
894static void l2cap_send_sframe(struct l2cap_chan *chan,
895 struct l2cap_ctrl *control)
896{
897 struct sk_buff *skb;
898 u32 control_field;
899
900 BT_DBG("chan %p, control %p", chan, control);
901
902 if (!control->sframe)
903 return;
904
905 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
906 !control->poll)
907 control->final = 1;
908
909 if (control->super == L2CAP_SUPER_RR)
910 clear_bit(CONN_RNR_SENT, &chan->conn_state);
911 else if (control->super == L2CAP_SUPER_RNR)
912 set_bit(CONN_RNR_SENT, &chan->conn_state);
913
914 if (control->super != L2CAP_SUPER_SREJ) {
915 chan->last_acked_seq = control->reqseq;
916 __clear_ack_timer(chan);
917 }
918
919 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
920 control->final, control->poll, control->super);
921
922 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
923 control_field = __pack_extended_control(control);
924 else
925 control_field = __pack_enhanced_control(control);
926
927 skb = l2cap_create_sframe_pdu(chan, control_field);
928 if (!IS_ERR(skb))
929 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300930}
931
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700932static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300933{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700934 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300935
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700936 BT_DBG("chan %p, poll %d", chan, poll);
937
938 memset(&control, 0, sizeof(control));
939 control.sframe = 1;
940 control.poll = poll;
941
942 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
943 control.super = L2CAP_SUPER_RNR;
944 else
945 control.super = L2CAP_SUPER_RR;
946
947 control.reqseq = chan->buffer_seq;
948 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300949}
950
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300951static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300952{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -0300953 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300954}
955
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +0200956static void l2cap_send_conn_req(struct l2cap_chan *chan)
957{
958 struct l2cap_conn *conn = chan->conn;
959 struct l2cap_conn_req req;
960
961 req.scid = cpu_to_le16(chan->scid);
962 req.psm = chan->psm;
963
964 chan->ident = l2cap_get_ident(conn);
965
966 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
967
968 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
969}
970
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300971static void l2cap_chan_ready(struct l2cap_chan *chan)
972{
973 struct sock *sk = chan->sk;
974 struct sock *parent;
975
976 lock_sock(sk);
977
978 parent = bt_sk(sk)->parent;
979
980 BT_DBG("sk %p, parent %p", sk, parent);
981
Mat Martineau28270112012-05-17 21:14:09 -0700982 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300983 chan->conf_state = 0;
984 __clear_chan_timer(chan);
985
986 __l2cap_state_change(chan, BT_CONNECTED);
987 sk->sk_state_change(sk);
988
989 if (parent)
990 parent->sk_data_ready(parent, 0);
991
992 release_sock(sk);
993}
994
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -0300995static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200996{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300997 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200998
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300999 if (conn->hcon->type == LE_LINK) {
1000 l2cap_chan_ready(chan);
1001 return;
1002 }
1003
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001004 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001005 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1006 return;
1007
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001008 if (l2cap_chan_check_security(chan) &&
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001009 __l2cap_no_conn_pending(chan))
1010 l2cap_send_conn_req(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001011 } else {
1012 struct l2cap_info_req req;
1013 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
1014
1015 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1016 conn->info_ident = l2cap_get_ident(conn);
1017
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001018 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001019
1020 l2cap_send_cmd(conn, conn->info_ident,
1021 L2CAP_INFO_REQ, sizeof(req), &req);
1022 }
1023}
1024
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001025static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1026{
1027 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001028 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001029 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1030
1031 switch (mode) {
1032 case L2CAP_MODE_ERTM:
1033 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1034 case L2CAP_MODE_STREAMING:
1035 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1036 default:
1037 return 0x00;
1038 }
1039}
1040
Gustavo F. Padovan4519de92011-04-28 17:55:53 -03001041static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001042{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001043 struct sock *sk = chan->sk;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001044 struct l2cap_disconn_req req;
1045
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001046 if (!conn)
1047 return;
1048
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001049 if (chan->mode == L2CAP_MODE_ERTM) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001050 __clear_retrans_timer(chan);
1051 __clear_monitor_timer(chan);
1052 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001053 }
1054
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001055 req.dcid = cpu_to_le16(chan->dcid);
1056 req.scid = cpu_to_le16(chan->scid);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001057 l2cap_send_cmd(conn, l2cap_get_ident(conn),
1058 L2CAP_DISCONN_REQ, sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001059
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001060 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001061 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001062 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001063 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001064}
1065
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001067static void l2cap_conn_start(struct l2cap_conn *conn)
1068{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001069 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001070
1071 BT_DBG("conn %p", conn);
1072
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001073 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001074
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001075 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001076 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001077
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001078 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001079
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001080 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001081 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001082 continue;
1083 }
1084
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001085 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001086 if (!l2cap_chan_check_security(chan) ||
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001087 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001088 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001089 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001090 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001091
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001092 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
1093 && test_bit(CONF_STATE2_DEVICE,
1094 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001095 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001096 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001097 continue;
1098 }
1099
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001100 l2cap_send_conn_req(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001101
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001102 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001103 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001104 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001105 rsp.scid = cpu_to_le16(chan->dcid);
1106 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001107
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001108 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001109 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001110 if (test_bit(BT_SK_DEFER_SETUP,
1111 &bt_sk(sk)->flags)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001112 struct sock *parent = bt_sk(sk)->parent;
1113 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
1114 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Ilia Kolomisnky05e9a2f2011-07-15 18:30:21 +00001115 if (parent)
1116 parent->sk_data_ready(parent, 0);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001117
1118 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001119 __l2cap_state_change(chan, BT_CONFIG);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001120 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1121 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1122 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001123 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001124 } else {
1125 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
1126 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
1127 }
1128
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001129 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
1130 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001131
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001132 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001133 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001134 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001135 continue;
1136 }
1137
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001138 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001139 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001140 l2cap_build_conf_req(chan, buf), buf);
1141 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001142 }
1143
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001144 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001145 }
1146
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001147 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001148}
1149
Ido Yarivc2287682012-04-20 15:46:07 -03001150/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001151 * Returns closest match, locked.
1152 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001153static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001154 bdaddr_t *src,
1155 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001156{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001157 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001158
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001159 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001160
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001161 list_for_each_entry(c, &chan_list, global_l) {
1162 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001163
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001164 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001165 continue;
1166
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001167 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001168 int src_match, dst_match;
1169 int src_any, dst_any;
1170
Ville Tervob62f3282011-02-10 22:38:50 -03001171 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001172 src_match = !bacmp(&bt_sk(sk)->src, src);
1173 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1174 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001175 read_unlock(&chan_list_lock);
1176 return c;
1177 }
Ville Tervob62f3282011-02-10 22:38:50 -03001178
1179 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001180 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1181 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1182 if ((src_match && dst_any) || (src_any && dst_match) ||
1183 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001184 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001185 }
1186 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001187
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001188 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001189
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001190 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001191}
1192
1193static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1194{
Gustavo F. Padovanc916fbe2011-04-04 16:00:55 -03001195 struct sock *parent, *sk;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001196 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001197
1198 BT_DBG("");
1199
1200 /* Check if we have socket listening on cid */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001201 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
Ido Yarivc2287682012-04-20 15:46:07 -03001202 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001203 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001204 return;
1205
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001206 parent = pchan->sk;
1207
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001208 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001209
Ville Tervob62f3282011-02-10 22:38:50 -03001210 /* Check for backlog size */
1211 if (sk_acceptq_is_full(parent)) {
1212 BT_DBG("backlog full %d", parent->sk_ack_backlog);
1213 goto clean;
1214 }
1215
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001216 chan = pchan->ops->new_connection(pchan->data);
1217 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001218 goto clean;
1219
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001220 sk = chan->sk;
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001221
Ville Tervob62f3282011-02-10 22:38:50 -03001222 hci_conn_hold(conn->hcon);
1223
Ville Tervob62f3282011-02-10 22:38:50 -03001224 bacpy(&bt_sk(sk)->src, conn->src);
1225 bacpy(&bt_sk(sk)->dst, conn->dst);
1226
Gustavo F. Padovand1010242011-03-25 00:39:48 -03001227 bt_accept_enqueue(parent, sk);
1228
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001229 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001230
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001231 __set_chan_timer(chan, sk->sk_sndtimeo);
Ville Tervob62f3282011-02-10 22:38:50 -03001232
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001233 __l2cap_state_change(chan, BT_CONNECTED);
Ville Tervob62f3282011-02-10 22:38:50 -03001234 parent->sk_data_ready(parent, 0);
1235
Ville Tervob62f3282011-02-10 22:38:50 -03001236clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001237 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001238}
1239
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001240static void l2cap_conn_ready(struct l2cap_conn *conn)
1241{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001242 struct l2cap_chan *chan;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001243
1244 BT_DBG("conn %p", conn);
1245
Ville Tervob62f3282011-02-10 22:38:50 -03001246 if (!conn->hcon->out && conn->hcon->type == LE_LINK)
1247 l2cap_le_conn_ready(conn);
1248
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001249 if (conn->hcon->out && conn->hcon->type == LE_LINK)
1250 smp_conn_security(conn, conn->hcon->pending_sec_level);
1251
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001252 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001253
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001254 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001255
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001256 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001257
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001258 if (conn->hcon->type == LE_LINK) {
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001259 if (smp_conn_security(conn, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001260 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001261
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001262 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001263 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001264 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001265 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001266 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001267 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001268 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001269
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001270 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001271 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001272
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001273 l2cap_chan_unlock(chan);
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
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001279/* Notify sockets that we cannot guaranty reliability anymore */
1280static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1281{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001282 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001283
1284 BT_DBG("conn %p", conn);
1285
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001286 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001287
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001288 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001289 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001290 __l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001291 }
1292
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001293 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001294}
1295
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001296static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001297{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001298 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001299 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001300
Marcel Holtmann984947d2009-02-06 23:35:19 +01001301 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001302 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001303
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001304 l2cap_conn_start(conn);
1305}
1306
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001307static void l2cap_conn_del(struct hci_conn *hcon, int err)
1308{
1309 struct l2cap_conn *conn = hcon->l2cap_data;
1310 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001311
1312 if (!conn)
1313 return;
1314
1315 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1316
1317 kfree_skb(conn->rx_skb);
1318
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001319 mutex_lock(&conn->chan_lock);
1320
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001321 /* Kill channels */
1322 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001323 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001324 l2cap_chan_lock(chan);
1325
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001326 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001327
1328 l2cap_chan_unlock(chan);
1329
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001330 chan->ops->close(chan->data);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001331 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001332 }
1333
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001334 mutex_unlock(&conn->chan_lock);
1335
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001336 hci_chan_del(conn->hchan);
1337
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001338 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001339 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001340
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001341 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001342 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001343 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001344 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001345
1346 hcon->l2cap_data = NULL;
1347 kfree(conn);
1348}
1349
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001350static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001351{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001352 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
1353 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001354
1355 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1356}
1357
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
1359{
Marcel Holtmann01394182006-07-03 10:02:46 +02001360 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001361 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362
Marcel Holtmann01394182006-07-03 10:02:46 +02001363 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364 return conn;
1365
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001366 hchan = hci_chan_create(hcon);
1367 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001368 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001370 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
1371 if (!conn) {
1372 hci_chan_del(hchan);
1373 return NULL;
1374 }
1375
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376 hcon->l2cap_data = conn;
1377 conn->hcon = hcon;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001378 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001380 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001381
Ville Tervoacd7d372011-02-10 22:38:49 -03001382 if (hcon->hdev->le_mtu && hcon->type == LE_LINK)
1383 conn->mtu = hcon->hdev->le_mtu;
1384 else
1385 conn->mtu = hcon->hdev->acl_mtu;
1386
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387 conn->src = &hcon->hdev->bdaddr;
1388 conn->dst = &hcon->dst;
1389
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001390 conn->feat_mask = 0;
1391
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001393 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001394
1395 INIT_LIST_HEAD(&conn->chan_l);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001397 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001398 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001399 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001400 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001401
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001402 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001403
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404 return conn;
1405}
1406
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408
Ido Yarivc2287682012-04-20 15:46:07 -03001409/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410 * Returns closest match.
1411 */
Ido Yarivc2287682012-04-20 15:46:07 -03001412static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1413 bdaddr_t *src,
1414 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001416 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001417
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001418 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001419
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001420 list_for_each_entry(c, &chan_list, global_l) {
1421 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001422
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001423 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424 continue;
1425
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001426 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001427 int src_match, dst_match;
1428 int src_any, dst_any;
1429
Linus Torvalds1da177e2005-04-16 15:20:36 -07001430 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001431 src_match = !bacmp(&bt_sk(sk)->src, src);
1432 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1433 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001434 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001435 return c;
1436 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437
1438 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001439 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1440 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1441 if ((src_match && dst_any) || (src_any && dst_match) ||
1442 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001443 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444 }
1445 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001447 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001448
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001449 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001450}
1451
Andre Guedes8e9f9892012-04-24 21:02:55 -03001452int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1453 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001455 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001457 struct l2cap_conn *conn;
1458 struct hci_conn *hcon;
1459 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001460 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001461 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462
Andre Guedes8e9f9892012-04-24 21:02:55 -03001463 BT_DBG("%s -> %s (type %u) psm 0x%2.2x", batostr(src), batostr(dst),
1464 dst_type, __le16_to_cpu(chan->psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001466 hdev = hci_get_route(dst, src);
1467 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468 return -EHOSTUNREACH;
1469
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001470 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001472 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001473
1474 /* PSM must be odd and lsb of upper byte must be 0 */
1475 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
1476 chan->chan_type != L2CAP_CHAN_RAW) {
1477 err = -EINVAL;
1478 goto done;
1479 }
1480
1481 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1482 err = -EINVAL;
1483 goto done;
1484 }
1485
1486 switch (chan->mode) {
1487 case L2CAP_MODE_BASIC:
1488 break;
1489 case L2CAP_MODE_ERTM:
1490 case L2CAP_MODE_STREAMING:
1491 if (!disable_ertm)
1492 break;
1493 /* fall through */
1494 default:
1495 err = -ENOTSUPP;
1496 goto done;
1497 }
1498
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001499 lock_sock(sk);
1500
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001501 switch (sk->sk_state) {
1502 case BT_CONNECT:
1503 case BT_CONNECT2:
1504 case BT_CONFIG:
1505 /* Already connecting */
1506 err = 0;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001507 release_sock(sk);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001508 goto done;
1509
1510 case BT_CONNECTED:
1511 /* Already connected */
1512 err = -EISCONN;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001513 release_sock(sk);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001514 goto done;
1515
1516 case BT_OPEN:
1517 case BT_BOUND:
1518 /* Can connect */
1519 break;
1520
1521 default:
1522 err = -EBADFD;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001523 release_sock(sk);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001524 goto done;
1525 }
1526
1527 /* Set destination address and psm */
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001528 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001529
1530 release_sock(sk);
1531
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001532 chan->psm = psm;
1533 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001535 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001536
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001537 if (chan->dcid == L2CAP_CID_LE_DATA)
Andre Guedes8e9f9892012-04-24 21:02:55 -03001538 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001539 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001540 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001541 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001542 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001543
Ville Tervo30e76272011-02-22 16:10:53 -03001544 if (IS_ERR(hcon)) {
1545 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001547 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548
1549 conn = l2cap_conn_add(hcon, 0);
1550 if (!conn) {
1551 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001552 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553 goto done;
1554 }
1555
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001556 if (hcon->type == LE_LINK) {
1557 err = 0;
1558
1559 if (!list_empty(&conn->chan_l)) {
1560 err = -EBUSY;
1561 hci_conn_put(hcon);
1562 }
1563
1564 if (err)
1565 goto done;
1566 }
1567
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568 /* Update source addr of the socket */
1569 bacpy(src, conn->src);
1570
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001571 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001572 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001573 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001574
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001575 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001576 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577
1578 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001579 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001580 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001581 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001582 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001583 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001584 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585 }
1586
Ville Tervo30e76272011-02-22 16:10:53 -03001587 err = 0;
1588
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001590 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001591 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592 hci_dev_put(hdev);
1593 return err;
1594}
1595
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001596int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001597{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001598 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001599 DECLARE_WAITQUEUE(wait, current);
1600 int err = 0;
1601 int timeo = HZ/5;
1602
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001603 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001604 set_current_state(TASK_INTERRUPTIBLE);
1605 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001606 if (!timeo)
1607 timeo = HZ/5;
1608
1609 if (signal_pending(current)) {
1610 err = sock_intr_errno(timeo);
1611 break;
1612 }
1613
1614 release_sock(sk);
1615 timeo = schedule_timeout(timeo);
1616 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001617 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001618
1619 err = sock_error(sk);
1620 if (err)
1621 break;
1622 }
1623 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001624 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001625 return err;
1626}
1627
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001628static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001629{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001630 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001631 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001632
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001633 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001634
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001635 l2cap_chan_lock(chan);
1636
Mat Martineau80909e02012-05-17 20:53:50 -07001637 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001638 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001639 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001640 return;
1641 }
1642
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001643 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001644
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001645 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001646 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001647}
1648
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001649static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001650{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001651 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001652 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001653
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001654 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001655
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001656 l2cap_chan_lock(chan);
1657
Mat Martineau80909e02012-05-17 20:53:50 -07001658 if (!chan->conn) {
1659 l2cap_chan_unlock(chan);
1660 l2cap_chan_put(chan);
1661 return;
1662 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001663
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001664 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001665 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001666 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001667}
1668
Gustavo Padovand6603662012-05-21 13:58:22 -03001669static void l2cap_streaming_send(struct l2cap_chan *chan,
1670 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001671{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001672 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001673 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001674
Mat Martineau37339372012-05-17 20:53:33 -07001675 BT_DBG("chan %p, skbs %p", chan, skbs);
1676
Mat Martineau37339372012-05-17 20:53:33 -07001677 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1678
1679 while (!skb_queue_empty(&chan->tx_q)) {
1680
1681 skb = skb_dequeue(&chan->tx_q);
1682
1683 bt_cb(skb)->control.retries = 1;
1684 control = &bt_cb(skb)->control;
1685
1686 control->reqseq = 0;
1687 control->txseq = chan->next_tx_seq;
1688
1689 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001690
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001691 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001692 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1693 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001694 }
1695
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001696 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001697
Mat Martineau37339372012-05-17 20:53:33 -07001698 BT_DBG("Sent txseq %d", (int)control->txseq);
1699
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001700 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001701 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001702 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001703}
1704
Szymon Janc67c9e842011-07-28 16:24:33 +02001705static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001706{
1707 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001708 struct l2cap_ctrl *control;
1709 int sent = 0;
1710
1711 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001712
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001713 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001714 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001715
Mat Martineau94122bb2012-05-02 09:42:02 -07001716 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1717 return 0;
1718
Mat Martineau18a48e72012-05-17 20:53:34 -07001719 while (chan->tx_send_head &&
1720 chan->unacked_frames < chan->remote_tx_win &&
1721 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001722
Mat Martineau18a48e72012-05-17 20:53:34 -07001723 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001724
Mat Martineau18a48e72012-05-17 20:53:34 -07001725 bt_cb(skb)->control.retries = 1;
1726 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001727
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001728 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001729 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001730
Mat Martineau18a48e72012-05-17 20:53:34 -07001731 control->reqseq = chan->buffer_seq;
1732 chan->last_acked_seq = chan->buffer_seq;
1733 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001734
Mat Martineau18a48e72012-05-17 20:53:34 -07001735 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001736
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001737 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001738 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1739 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001740 }
1741
Mat Martineau18a48e72012-05-17 20:53:34 -07001742 /* Clone after data has been modified. Data is assumed to be
1743 read-only (for locking purposes) on cloned sk_buffs.
1744 */
1745 tx_skb = skb_clone(skb, GFP_KERNEL);
1746
1747 if (!tx_skb)
1748 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001749
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001750 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001751
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001752 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07001753 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03001754 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07001755 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001756
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001757 if (skb_queue_is_last(&chan->tx_q, skb))
1758 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001759 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001760 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07001761
1762 l2cap_do_send(chan, tx_skb);
1763 BT_DBG("Sent txseq %d", (int)control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001764 }
1765
Mat Martineau18a48e72012-05-17 20:53:34 -07001766 BT_DBG("Sent %d, %d unacked, %d in ERTM queue", sent,
1767 (int) chan->unacked_frames, skb_queue_len(&chan->tx_q));
1768
1769 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001770}
1771
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001772static void l2cap_ertm_resend(struct l2cap_chan *chan)
1773{
1774 struct l2cap_ctrl control;
1775 struct sk_buff *skb;
1776 struct sk_buff *tx_skb;
1777 u16 seq;
1778
1779 BT_DBG("chan %p", chan);
1780
1781 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1782 return;
1783
1784 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
1785 seq = l2cap_seq_list_pop(&chan->retrans_list);
1786
1787 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
1788 if (!skb) {
1789 BT_DBG("Error: Can't retransmit seq %d, frame missing",
1790 seq);
1791 continue;
1792 }
1793
1794 bt_cb(skb)->control.retries++;
1795 control = bt_cb(skb)->control;
1796
1797 if (chan->max_tx != 0 &&
1798 bt_cb(skb)->control.retries > chan->max_tx) {
1799 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
1800 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
1801 l2cap_seq_list_clear(&chan->retrans_list);
1802 break;
1803 }
1804
1805 control.reqseq = chan->buffer_seq;
1806 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
1807 control.final = 1;
1808 else
1809 control.final = 0;
1810
1811 if (skb_cloned(skb)) {
1812 /* Cloned sk_buffs are read-only, so we need a
1813 * writeable copy
1814 */
1815 tx_skb = skb_copy(skb, GFP_ATOMIC);
1816 } else {
1817 tx_skb = skb_clone(skb, GFP_ATOMIC);
1818 }
1819
1820 if (!tx_skb) {
1821 l2cap_seq_list_clear(&chan->retrans_list);
1822 break;
1823 }
1824
1825 /* Update skb contents */
1826 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
1827 put_unaligned_le32(__pack_extended_control(&control),
1828 tx_skb->data + L2CAP_HDR_SIZE);
1829 } else {
1830 put_unaligned_le16(__pack_enhanced_control(&control),
1831 tx_skb->data + L2CAP_HDR_SIZE);
1832 }
1833
1834 if (chan->fcs == L2CAP_FCS_CRC16) {
1835 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
1836 put_unaligned_le16(fcs, skb_put(tx_skb,
1837 L2CAP_FCS_SIZE));
1838 }
1839
1840 l2cap_do_send(chan, tx_skb);
1841
1842 BT_DBG("Resent txseq %d", control.txseq);
1843
1844 chan->last_acked_seq = chan->buffer_seq;
1845 }
1846}
1847
Mat Martineauf80842a2012-05-17 20:53:46 -07001848static void l2cap_retransmit(struct l2cap_chan *chan,
1849 struct l2cap_ctrl *control)
1850{
1851 BT_DBG("chan %p, control %p", chan, control);
1852
1853 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
1854 l2cap_ertm_resend(chan);
1855}
1856
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001857static void l2cap_retransmit_all(struct l2cap_chan *chan,
1858 struct l2cap_ctrl *control)
1859{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001860 struct sk_buff *skb;
1861
1862 BT_DBG("chan %p, control %p", chan, control);
1863
1864 if (control->poll)
1865 set_bit(CONN_SEND_FBIT, &chan->conn_state);
1866
1867 l2cap_seq_list_clear(&chan->retrans_list);
1868
1869 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1870 return;
1871
1872 if (chan->unacked_frames) {
1873 skb_queue_walk(&chan->tx_q, skb) {
1874 if (bt_cb(skb)->control.txseq == control->reqseq ||
1875 skb == chan->tx_send_head)
1876 break;
1877 }
1878
1879 skb_queue_walk_from(&chan->tx_q, skb) {
1880 if (skb == chan->tx_send_head)
1881 break;
1882
1883 l2cap_seq_list_append(&chan->retrans_list,
1884 bt_cb(skb)->control.txseq);
1885 }
1886
1887 l2cap_ertm_resend(chan);
1888 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001889}
1890
Szymon Jancb17e73b2012-01-11 10:59:47 +01001891static void l2cap_send_ack(struct l2cap_chan *chan)
1892{
Mat Martineau0a0aba42012-05-17 20:53:39 -07001893 struct l2cap_ctrl control;
1894 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
1895 chan->last_acked_seq);
1896 int threshold;
1897
1898 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
1899 chan, chan->last_acked_seq, chan->buffer_seq);
1900
1901 memset(&control, 0, sizeof(control));
1902 control.sframe = 1;
1903
1904 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
1905 chan->rx_state == L2CAP_RX_STATE_RECV) {
1906 __clear_ack_timer(chan);
1907 control.super = L2CAP_SUPER_RNR;
1908 control.reqseq = chan->buffer_seq;
1909 l2cap_send_sframe(chan, &control);
1910 } else {
1911 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
1912 l2cap_ertm_send(chan);
1913 /* If any i-frames were sent, they included an ack */
1914 if (chan->buffer_seq == chan->last_acked_seq)
1915 frames_to_ack = 0;
1916 }
1917
1918 /* Ack now if the tx window is 3/4ths full.
1919 * Calculate without mul or div
1920 */
1921 threshold = chan->tx_win;
1922 threshold += threshold << 1;
1923 threshold >>= 2;
1924
1925 BT_DBG("frames_to_ack %d, threshold %d", (int)frames_to_ack,
1926 threshold);
1927
1928 if (frames_to_ack >= threshold) {
1929 __clear_ack_timer(chan);
1930 control.super = L2CAP_SUPER_RR;
1931 control.reqseq = chan->buffer_seq;
1932 l2cap_send_sframe(chan, &control);
1933 frames_to_ack = 0;
1934 }
1935
1936 if (frames_to_ack)
1937 __set_ack_timer(chan);
1938 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01001939}
1940
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001941static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
1942 struct msghdr *msg, int len,
1943 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02001945 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001946 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03001947 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001949 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001950 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001951
1952 sent += count;
1953 len -= count;
1954
1955 /* Continuation fragments (no L2CAP header) */
1956 frag = &skb_shinfo(skb)->frag_list;
1957 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001958 struct sk_buff *tmp;
1959
Linus Torvalds1da177e2005-04-16 15:20:36 -07001960 count = min_t(unsigned int, conn->mtu, len);
1961
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001962 tmp = chan->ops->alloc_skb(chan, count,
1963 msg->msg_flags & MSG_DONTWAIT);
1964 if (IS_ERR(tmp))
1965 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001966
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001967 *frag = tmp;
1968
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001969 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1970 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001971
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001972 (*frag)->priority = skb->priority;
1973
Linus Torvalds1da177e2005-04-16 15:20:36 -07001974 sent += count;
1975 len -= count;
1976
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03001977 skb->len += (*frag)->len;
1978 skb->data_len += (*frag)->len;
1979
Linus Torvalds1da177e2005-04-16 15:20:36 -07001980 frag = &(*frag)->next;
1981 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001982
1983 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001984}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001985
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001986static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
1987 struct msghdr *msg, size_t len,
1988 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001989{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001990 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001991 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03001992 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001993 struct l2cap_hdr *lh;
1994
Andrei Emeltchenko6d5922b2012-02-06 15:04:01 +02001995 BT_DBG("chan %p len %d priority %u", chan, (int)len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001996
1997 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001998
1999 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002000 msg->msg_flags & MSG_DONTWAIT);
2001 if (IS_ERR(skb))
2002 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002003
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002004 skb->priority = priority;
2005
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002006 /* Create L2CAP header */
2007 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002008 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002009 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
2010 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002011
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002012 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002013 if (unlikely(err < 0)) {
2014 kfree_skb(skb);
2015 return ERR_PTR(err);
2016 }
2017 return skb;
2018}
2019
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002020static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
2021 struct msghdr *msg, size_t len,
2022 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002023{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002024 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002025 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002026 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002027 struct l2cap_hdr *lh;
2028
Andrei Emeltchenko6d5922b2012-02-06 15:04:01 +02002029 BT_DBG("chan %p len %d", chan, (int)len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002030
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002031 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002032
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002033 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002034 msg->msg_flags & MSG_DONTWAIT);
2035 if (IS_ERR(skb))
2036 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002037
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002038 skb->priority = priority;
2039
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002040 /* Create L2CAP header */
2041 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002042 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002043 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002044
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002045 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002046 if (unlikely(err < 0)) {
2047 kfree_skb(skb);
2048 return ERR_PTR(err);
2049 }
2050 return skb;
2051}
2052
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002053static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
2054 struct msghdr *msg, size_t len,
Mat Martineau94122bb2012-05-02 09:42:02 -07002055 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002056{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002057 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002058 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002059 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002060 struct l2cap_hdr *lh;
2061
Andrei Emeltchenko6d5922b2012-02-06 15:04:01 +02002062 BT_DBG("chan %p len %d", chan, (int)len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002063
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002064 if (!conn)
2065 return ERR_PTR(-ENOTCONN);
2066
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002067 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2068 hlen = L2CAP_EXT_HDR_SIZE;
2069 else
2070 hlen = L2CAP_ENH_HDR_SIZE;
2071
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002072 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002073 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002074
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002075 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002076 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002077
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002078 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002079
2080 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002081 msg->msg_flags & MSG_DONTWAIT);
2082 if (IS_ERR(skb))
2083 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002084
2085 /* Create L2CAP header */
2086 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002087 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002088 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002089
Mat Martineau18a48e72012-05-17 20:53:34 -07002090 /* Control header is populated later */
2091 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2092 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2093 else
2094 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002095
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002096 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002097 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002098
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002099 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002100 if (unlikely(err < 0)) {
2101 kfree_skb(skb);
2102 return ERR_PTR(err);
2103 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002104
Mat Martineau18a48e72012-05-17 20:53:34 -07002105 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002106 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002107 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002108}
2109
Mat Martineau94122bb2012-05-02 09:42:02 -07002110static int l2cap_segment_sdu(struct l2cap_chan *chan,
2111 struct sk_buff_head *seg_queue,
2112 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002113{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002114 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002115 u16 sdu_len;
2116 size_t pdu_len;
2117 int err = 0;
2118 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002119
Mat Martineau94122bb2012-05-02 09:42:02 -07002120 BT_DBG("chan %p, msg %p, len %d", chan, msg, (int)len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002121
Mat Martineau94122bb2012-05-02 09:42:02 -07002122 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2123 * so fragmented skbs are not used. The HCI layer's handling
2124 * of fragmented skbs is not compatible with ERTM's queueing.
2125 */
2126
2127 /* PDU size is derived from the HCI MTU */
2128 pdu_len = chan->conn->mtu;
2129
2130 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
2131
2132 /* Adjust for largest possible L2CAP overhead. */
2133 pdu_len -= L2CAP_EXT_HDR_SIZE + L2CAP_FCS_SIZE;
2134
2135 /* Remote device may have requested smaller PDUs */
2136 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2137
2138 if (len <= pdu_len) {
2139 sar = L2CAP_SAR_UNSEGMENTED;
2140 sdu_len = 0;
2141 pdu_len = len;
2142 } else {
2143 sar = L2CAP_SAR_START;
2144 sdu_len = len;
2145 pdu_len -= L2CAP_SDULEN_SIZE;
2146 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002147
2148 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002149 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002150
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002151 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002152 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002153 return PTR_ERR(skb);
2154 }
2155
Mat Martineau94122bb2012-05-02 09:42:02 -07002156 bt_cb(skb)->control.sar = sar;
2157 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002158
Mat Martineau94122bb2012-05-02 09:42:02 -07002159 len -= pdu_len;
2160 if (sdu_len) {
2161 sdu_len = 0;
2162 pdu_len += L2CAP_SDULEN_SIZE;
2163 }
2164
2165 if (len <= pdu_len) {
2166 sar = L2CAP_SAR_END;
2167 pdu_len = len;
2168 } else {
2169 sar = L2CAP_SAR_CONTINUE;
2170 }
2171 }
2172
2173 return err;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002174}
2175
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002176int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
2177 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002178{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002179 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002180 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002181 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002182
2183 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002184 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002185 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002186 if (IS_ERR(skb))
2187 return PTR_ERR(skb);
2188
2189 l2cap_do_send(chan, skb);
2190 return len;
2191 }
2192
2193 switch (chan->mode) {
2194 case L2CAP_MODE_BASIC:
2195 /* Check outgoing MTU */
2196 if (len > chan->omtu)
2197 return -EMSGSIZE;
2198
2199 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002200 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002201 if (IS_ERR(skb))
2202 return PTR_ERR(skb);
2203
2204 l2cap_do_send(chan, skb);
2205 err = len;
2206 break;
2207
2208 case L2CAP_MODE_ERTM:
2209 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002210 /* Check outgoing MTU */
2211 if (len > chan->omtu) {
2212 err = -EMSGSIZE;
2213 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002214 }
2215
Mat Martineau94122bb2012-05-02 09:42:02 -07002216 __skb_queue_head_init(&seg_queue);
2217
2218 /* Do segmentation before calling in to the state machine,
2219 * since it's possible to block while waiting for memory
2220 * allocation.
2221 */
2222 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2223
2224 /* The channel could have been closed while segmenting,
2225 * check that it is still connected.
2226 */
2227 if (chan->state != BT_CONNECTED) {
2228 __skb_queue_purge(&seg_queue);
2229 err = -ENOTCONN;
2230 }
2231
2232 if (err)
2233 break;
2234
Mat Martineau37339372012-05-17 20:53:33 -07002235 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002236 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002237 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002238 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002239
Gustavo Padovand6603662012-05-21 13:58:22 -03002240 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002241
Mat Martineau94122bb2012-05-02 09:42:02 -07002242 /* If the skbs were not queued for sending, they'll still be in
2243 * seg_queue and need to be purged.
2244 */
2245 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002246 break;
2247
2248 default:
2249 BT_DBG("bad state %1.1x", chan->mode);
2250 err = -EBADFD;
2251 }
2252
2253 return err;
2254}
2255
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002256static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2257{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002258 struct l2cap_ctrl control;
2259 u16 seq;
2260
2261 BT_DBG("chan %p, txseq %d", chan, txseq);
2262
2263 memset(&control, 0, sizeof(control));
2264 control.sframe = 1;
2265 control.super = L2CAP_SUPER_SREJ;
2266
2267 for (seq = chan->expected_tx_seq; seq != txseq;
2268 seq = __next_seq(chan, seq)) {
2269 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2270 control.reqseq = seq;
2271 l2cap_send_sframe(chan, &control);
2272 l2cap_seq_list_append(&chan->srej_list, seq);
2273 }
2274 }
2275
2276 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002277}
2278
2279static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2280{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002281 struct l2cap_ctrl control;
2282
2283 BT_DBG("chan %p", chan);
2284
2285 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2286 return;
2287
2288 memset(&control, 0, sizeof(control));
2289 control.sframe = 1;
2290 control.super = L2CAP_SUPER_SREJ;
2291 control.reqseq = chan->srej_list.tail;
2292 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002293}
2294
2295static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2296{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002297 struct l2cap_ctrl control;
2298 u16 initial_head;
2299 u16 seq;
2300
2301 BT_DBG("chan %p, txseq %d", chan, txseq);
2302
2303 memset(&control, 0, sizeof(control));
2304 control.sframe = 1;
2305 control.super = L2CAP_SUPER_SREJ;
2306
2307 /* Capture initial list head to allow only one pass through the list. */
2308 initial_head = chan->srej_list.head;
2309
2310 do {
2311 seq = l2cap_seq_list_pop(&chan->srej_list);
2312 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2313 break;
2314
2315 control.reqseq = seq;
2316 l2cap_send_sframe(chan, &control);
2317 l2cap_seq_list_append(&chan->srej_list, seq);
2318 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002319}
2320
Mat Martineau608bcc62012-05-17 20:53:32 -07002321static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2322{
2323 struct sk_buff *acked_skb;
2324 u16 ackseq;
2325
2326 BT_DBG("chan %p, reqseq %d", chan, reqseq);
2327
2328 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2329 return;
2330
2331 BT_DBG("expected_ack_seq %d, unacked_frames %d",
2332 chan->expected_ack_seq, chan->unacked_frames);
2333
2334 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2335 ackseq = __next_seq(chan, ackseq)) {
2336
2337 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2338 if (acked_skb) {
2339 skb_unlink(acked_skb, &chan->tx_q);
2340 kfree_skb(acked_skb);
2341 chan->unacked_frames--;
2342 }
2343 }
2344
2345 chan->expected_ack_seq = reqseq;
2346
2347 if (chan->unacked_frames == 0)
2348 __clear_retrans_timer(chan);
2349
2350 BT_DBG("unacked_frames %d", (int) chan->unacked_frames);
2351}
2352
2353static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2354{
2355 BT_DBG("chan %p", chan);
2356
2357 chan->expected_tx_seq = chan->buffer_seq;
2358 l2cap_seq_list_clear(&chan->srej_list);
2359 skb_queue_purge(&chan->srej_q);
2360 chan->rx_state = L2CAP_RX_STATE_RECV;
2361}
2362
Gustavo Padovand6603662012-05-21 13:58:22 -03002363static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2364 struct l2cap_ctrl *control,
2365 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002366{
Mat Martineau608bcc62012-05-17 20:53:32 -07002367 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2368 event);
2369
2370 switch (event) {
2371 case L2CAP_EV_DATA_REQUEST:
2372 if (chan->tx_send_head == NULL)
2373 chan->tx_send_head = skb_peek(skbs);
2374
2375 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2376 l2cap_ertm_send(chan);
2377 break;
2378 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2379 BT_DBG("Enter LOCAL_BUSY");
2380 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2381
2382 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2383 /* The SREJ_SENT state must be aborted if we are to
2384 * enter the LOCAL_BUSY state.
2385 */
2386 l2cap_abort_rx_srej_sent(chan);
2387 }
2388
2389 l2cap_send_ack(chan);
2390
2391 break;
2392 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2393 BT_DBG("Exit LOCAL_BUSY");
2394 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2395
2396 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2397 struct l2cap_ctrl local_control;
2398
2399 memset(&local_control, 0, sizeof(local_control));
2400 local_control.sframe = 1;
2401 local_control.super = L2CAP_SUPER_RR;
2402 local_control.poll = 1;
2403 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002404 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002405
2406 chan->retry_count = 1;
2407 __set_monitor_timer(chan);
2408 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2409 }
2410 break;
2411 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2412 l2cap_process_reqseq(chan, control->reqseq);
2413 break;
2414 case L2CAP_EV_EXPLICIT_POLL:
2415 l2cap_send_rr_or_rnr(chan, 1);
2416 chan->retry_count = 1;
2417 __set_monitor_timer(chan);
2418 __clear_ack_timer(chan);
2419 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2420 break;
2421 case L2CAP_EV_RETRANS_TO:
2422 l2cap_send_rr_or_rnr(chan, 1);
2423 chan->retry_count = 1;
2424 __set_monitor_timer(chan);
2425 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2426 break;
2427 case L2CAP_EV_RECV_FBIT:
2428 /* Nothing to process */
2429 break;
2430 default:
2431 break;
2432 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002433}
2434
Gustavo Padovand6603662012-05-21 13:58:22 -03002435static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2436 struct l2cap_ctrl *control,
2437 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002438{
Mat Martineau608bcc62012-05-17 20:53:32 -07002439 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2440 event);
2441
2442 switch (event) {
2443 case L2CAP_EV_DATA_REQUEST:
2444 if (chan->tx_send_head == NULL)
2445 chan->tx_send_head = skb_peek(skbs);
2446 /* Queue data, but don't send. */
2447 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2448 break;
2449 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2450 BT_DBG("Enter LOCAL_BUSY");
2451 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2452
2453 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2454 /* The SREJ_SENT state must be aborted if we are to
2455 * enter the LOCAL_BUSY state.
2456 */
2457 l2cap_abort_rx_srej_sent(chan);
2458 }
2459
2460 l2cap_send_ack(chan);
2461
2462 break;
2463 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2464 BT_DBG("Exit LOCAL_BUSY");
2465 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2466
2467 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2468 struct l2cap_ctrl local_control;
2469 memset(&local_control, 0, sizeof(local_control));
2470 local_control.sframe = 1;
2471 local_control.super = L2CAP_SUPER_RR;
2472 local_control.poll = 1;
2473 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002474 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002475
2476 chan->retry_count = 1;
2477 __set_monitor_timer(chan);
2478 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2479 }
2480 break;
2481 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2482 l2cap_process_reqseq(chan, control->reqseq);
2483
2484 /* Fall through */
2485
2486 case L2CAP_EV_RECV_FBIT:
2487 if (control && control->final) {
2488 __clear_monitor_timer(chan);
2489 if (chan->unacked_frames > 0)
2490 __set_retrans_timer(chan);
2491 chan->retry_count = 0;
2492 chan->tx_state = L2CAP_TX_STATE_XMIT;
2493 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2494 }
2495 break;
2496 case L2CAP_EV_EXPLICIT_POLL:
2497 /* Ignore */
2498 break;
2499 case L2CAP_EV_MONITOR_TO:
2500 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2501 l2cap_send_rr_or_rnr(chan, 1);
2502 __set_monitor_timer(chan);
2503 chan->retry_count++;
2504 } else {
2505 l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
2506 }
2507 break;
2508 default:
2509 break;
2510 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002511}
2512
Gustavo Padovand6603662012-05-21 13:58:22 -03002513static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2514 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002515{
Mat Martineau608bcc62012-05-17 20:53:32 -07002516 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2517 chan, control, skbs, event, chan->tx_state);
2518
2519 switch (chan->tx_state) {
2520 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002521 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002522 break;
2523 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002524 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002525 break;
2526 default:
2527 /* Ignore event */
2528 break;
2529 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002530}
2531
Mat Martineau4b51dae92012-05-17 20:53:37 -07002532static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2533 struct l2cap_ctrl *control)
2534{
2535 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002536 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002537}
2538
Mat Martineauf80842a2012-05-17 20:53:46 -07002539static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2540 struct l2cap_ctrl *control)
2541{
2542 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002543 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002544}
2545
Linus Torvalds1da177e2005-04-16 15:20:36 -07002546/* Copy frame to all raw sockets on that connection */
2547static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2548{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002549 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002550 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551
2552 BT_DBG("conn %p", conn);
2553
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002554 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002555
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002556 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002557 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002558 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002559 continue;
2560
2561 /* Don't send frame to the socket it came from */
2562 if (skb->sk == sk)
2563 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002564 nskb = skb_clone(skb, GFP_ATOMIC);
2565 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002566 continue;
2567
Gustavo F. Padovan23070492011-05-16 17:57:22 -03002568 if (chan->ops->recv(chan->data, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002569 kfree_skb(nskb);
2570 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002571
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002572 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002573}
2574
2575/* ---- L2CAP signalling commands ---- */
2576static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2577 u8 code, u8 ident, u16 dlen, void *data)
2578{
2579 struct sk_buff *skb, **frag;
2580 struct l2cap_cmd_hdr *cmd;
2581 struct l2cap_hdr *lh;
2582 int len, count;
2583
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002584 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2585 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002586
2587 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2588 count = min_t(unsigned int, conn->mtu, len);
2589
2590 skb = bt_skb_alloc(count, GFP_ATOMIC);
2591 if (!skb)
2592 return NULL;
2593
2594 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002595 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002596
2597 if (conn->hcon->type == LE_LINK)
2598 lh->cid = cpu_to_le16(L2CAP_CID_LE_SIGNALING);
2599 else
2600 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002601
2602 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2603 cmd->code = code;
2604 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002605 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002606
2607 if (dlen) {
2608 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2609 memcpy(skb_put(skb, count), data, count);
2610 data += count;
2611 }
2612
2613 len -= skb->len;
2614
2615 /* Continuation fragments (no L2CAP header) */
2616 frag = &skb_shinfo(skb)->frag_list;
2617 while (len) {
2618 count = min_t(unsigned int, conn->mtu, len);
2619
2620 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2621 if (!*frag)
2622 goto fail;
2623
2624 memcpy(skb_put(*frag, count), data, count);
2625
2626 len -= count;
2627 data += count;
2628
2629 frag = &(*frag)->next;
2630 }
2631
2632 return skb;
2633
2634fail:
2635 kfree_skb(skb);
2636 return NULL;
2637}
2638
2639static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2640{
2641 struct l2cap_conf_opt *opt = *ptr;
2642 int len;
2643
2644 len = L2CAP_CONF_OPT_SIZE + opt->len;
2645 *ptr += len;
2646
2647 *type = opt->type;
2648 *olen = opt->len;
2649
2650 switch (opt->len) {
2651 case 1:
2652 *val = *((u8 *) opt->val);
2653 break;
2654
2655 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002656 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002657 break;
2658
2659 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002660 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002661 break;
2662
2663 default:
2664 *val = (unsigned long) opt->val;
2665 break;
2666 }
2667
2668 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2669 return len;
2670}
2671
Linus Torvalds1da177e2005-04-16 15:20:36 -07002672static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2673{
2674 struct l2cap_conf_opt *opt = *ptr;
2675
2676 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2677
2678 opt->type = type;
2679 opt->len = len;
2680
2681 switch (len) {
2682 case 1:
2683 *((u8 *) opt->val) = val;
2684 break;
2685
2686 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002687 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002688 break;
2689
2690 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002691 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002692 break;
2693
2694 default:
2695 memcpy(opt->val, (void *) val, len);
2696 break;
2697 }
2698
2699 *ptr += L2CAP_CONF_OPT_SIZE + len;
2700}
2701
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002702static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2703{
2704 struct l2cap_conf_efs efs;
2705
Szymon Janc1ec918c2011-11-16 09:32:21 +01002706 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002707 case L2CAP_MODE_ERTM:
2708 efs.id = chan->local_id;
2709 efs.stype = chan->local_stype;
2710 efs.msdu = cpu_to_le16(chan->local_msdu);
2711 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2712 efs.acc_lat = cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
2713 efs.flush_to = cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO);
2714 break;
2715
2716 case L2CAP_MODE_STREAMING:
2717 efs.id = 1;
2718 efs.stype = L2CAP_SERV_BESTEFFORT;
2719 efs.msdu = cpu_to_le16(chan->local_msdu);
2720 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2721 efs.acc_lat = 0;
2722 efs.flush_to = 0;
2723 break;
2724
2725 default:
2726 return;
2727 }
2728
2729 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
2730 (unsigned long) &efs);
2731}
2732
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002733static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002734{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002735 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07002736 ack_timer.work);
2737 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002738
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02002739 BT_DBG("chan %p", chan);
2740
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002741 l2cap_chan_lock(chan);
2742
Mat Martineau03625202012-05-17 20:53:51 -07002743 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2744 chan->last_acked_seq);
2745
2746 if (frames_to_ack)
2747 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002748
2749 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01002750 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002751}
2752
Mat Martineau3c588192012-04-11 10:48:42 -07002753static inline int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002754{
Mat Martineau3c588192012-04-11 10:48:42 -07002755 int err;
2756
Mat Martineau105bdf92012-04-27 16:50:48 -07002757 chan->next_tx_seq = 0;
2758 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002759 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002760 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002761 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002762 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07002763 chan->last_acked_seq = 0;
2764 chan->sdu = NULL;
2765 chan->sdu_last_frag = NULL;
2766 chan->sdu_len = 0;
2767
Mat Martineaud34c34f2012-05-14 14:49:27 -07002768 skb_queue_head_init(&chan->tx_q);
2769
Mat Martineau105bdf92012-04-27 16:50:48 -07002770 if (chan->mode != L2CAP_MODE_ERTM)
2771 return 0;
2772
2773 chan->rx_state = L2CAP_RX_STATE_RECV;
2774 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002775
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002776 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
2777 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
2778 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002779
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03002780 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002781
Mat Martineau3c588192012-04-11 10:48:42 -07002782 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
2783 if (err < 0)
2784 return err;
2785
Mat Martineau9dc9aff2012-05-17 16:20:14 -07002786 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
2787 if (err < 0)
2788 l2cap_seq_list_free(&chan->srej_list);
2789
2790 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002791}
2792
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002793static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2794{
2795 switch (mode) {
2796 case L2CAP_MODE_STREAMING:
2797 case L2CAP_MODE_ERTM:
2798 if (l2cap_mode_supported(mode, remote_feat_mask))
2799 return mode;
2800 /* fall through */
2801 default:
2802 return L2CAP_MODE_BASIC;
2803 }
2804}
2805
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002806static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
2807{
2808 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
2809}
2810
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002811static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
2812{
2813 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
2814}
2815
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002816static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
2817{
2818 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002819 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002820 /* use extended control field */
2821 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002822 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
2823 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002824 chan->tx_win = min_t(u16, chan->tx_win,
2825 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002826 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
2827 }
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002828}
2829
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03002830static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002831{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002832 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002833 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002834 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002835 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002836
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03002837 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002838
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002839 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002840 goto done;
2841
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002842 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002843 case L2CAP_MODE_STREAMING:
2844 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002845 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002846 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002847
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002848 if (__l2cap_efs_supported(chan))
2849 set_bit(FLAG_EFS_ENABLE, &chan->flags);
2850
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002851 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002852 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002853 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002854 break;
2855 }
2856
2857done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002858 if (chan->imtu != L2CAP_DEFAULT_MTU)
2859 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02002860
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002861 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002862 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002863 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
2864 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002865 break;
2866
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002867 rfc.mode = L2CAP_MODE_BASIC;
2868 rfc.txwin_size = 0;
2869 rfc.max_transmit = 0;
2870 rfc.retrans_timeout = 0;
2871 rfc.monitor_timeout = 0;
2872 rfc.max_pdu_size = 0;
2873
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002874 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2875 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002876 break;
2877
2878 case L2CAP_MODE_ERTM:
2879 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002880 rfc.max_transmit = chan->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002881 rfc.retrans_timeout = 0;
2882 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002883
2884 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
2885 L2CAP_EXT_HDR_SIZE -
2886 L2CAP_SDULEN_SIZE -
2887 L2CAP_FCS_SIZE);
2888 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002889
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002890 l2cap_txwin_setup(chan);
2891
2892 rfc.txwin_size = min_t(u16, chan->tx_win,
2893 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002894
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002895 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2896 (unsigned long) &rfc);
2897
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002898 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2899 l2cap_add_opt_efs(&ptr, chan);
2900
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002901 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002902 break;
2903
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002904 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002905 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002906 chan->fcs = L2CAP_FCS_NONE;
2907 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002908 }
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002909
2910 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2911 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
2912 chan->tx_win);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002913 break;
2914
2915 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07002916 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002917 rfc.mode = L2CAP_MODE_STREAMING;
2918 rfc.txwin_size = 0;
2919 rfc.max_transmit = 0;
2920 rfc.retrans_timeout = 0;
2921 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002922
2923 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
2924 L2CAP_EXT_HDR_SIZE -
2925 L2CAP_SDULEN_SIZE -
2926 L2CAP_FCS_SIZE);
2927 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002928
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002929 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2930 (unsigned long) &rfc);
2931
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002932 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2933 l2cap_add_opt_efs(&ptr, chan);
2934
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002935 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002936 break;
2937
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002938 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002939 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002940 chan->fcs = L2CAP_FCS_NONE;
2941 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002942 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002943 break;
2944 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002945
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002946 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03002947 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002948
2949 return ptr - data;
2950}
2951
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002952static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002954 struct l2cap_conf_rsp *rsp = data;
2955 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002956 void *req = chan->conf_req;
2957 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002958 int type, hint, olen;
2959 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002960 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002961 struct l2cap_conf_efs efs;
2962 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02002963 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002964 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002965 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002966
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002967 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002968
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002969 while (len >= L2CAP_CONF_OPT_SIZE) {
2970 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002971
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002972 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002973 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002974
2975 switch (type) {
2976 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002977 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002978 break;
2979
2980 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002981 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002982 break;
2983
2984 case L2CAP_CONF_QOS:
2985 break;
2986
Marcel Holtmann6464f352007-10-20 13:39:51 +02002987 case L2CAP_CONF_RFC:
2988 if (olen == sizeof(rfc))
2989 memcpy(&rfc, (void *) val, olen);
2990 break;
2991
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002992 case L2CAP_CONF_FCS:
2993 if (val == L2CAP_FCS_NONE)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002994 set_bit(CONF_NO_FCS_RECV, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002995 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002996
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002997 case L2CAP_CONF_EFS:
2998 remote_efs = 1;
2999 if (olen == sizeof(efs))
3000 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003001 break;
3002
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003003 case L2CAP_CONF_EWS:
3004 if (!enable_hs)
3005 return -ECONNREFUSED;
3006
3007 set_bit(FLAG_EXT_CTRL, &chan->flags);
3008 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003009 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003010 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003011 break;
3012
3013 default:
3014 if (hint)
3015 break;
3016
3017 result = L2CAP_CONF_UNKNOWN;
3018 *((u8 *) ptr++) = type;
3019 break;
3020 }
3021 }
3022
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003023 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003024 goto done;
3025
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003026 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003027 case L2CAP_MODE_STREAMING:
3028 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003029 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003030 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003031 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003032 break;
3033 }
3034
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003035 if (remote_efs) {
3036 if (__l2cap_efs_supported(chan))
3037 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3038 else
3039 return -ECONNREFUSED;
3040 }
3041
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003042 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003043 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003044
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003045 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003046 }
3047
3048done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003049 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003050 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003051 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003052
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003053 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003054 return -ECONNREFUSED;
3055
3056 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3057 sizeof(rfc), (unsigned long) &rfc);
3058 }
3059
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003060 if (result == L2CAP_CONF_SUCCESS) {
3061 /* Configure output options and let the other side know
3062 * which ones we don't like. */
3063
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003064 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3065 result = L2CAP_CONF_UNACCEPT;
3066 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003067 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003068 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003069 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003070 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003071
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003072 if (remote_efs) {
3073 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
3074 efs.stype != L2CAP_SERV_NOTRAFIC &&
3075 efs.stype != chan->local_stype) {
3076
3077 result = L2CAP_CONF_UNACCEPT;
3078
3079 if (chan->num_conf_req >= 1)
3080 return -ECONNREFUSED;
3081
3082 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003083 sizeof(efs),
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003084 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003085 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003086 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003087 result = L2CAP_CONF_PENDING;
3088 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003089 }
3090 }
3091
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003092 switch (rfc.mode) {
3093 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003094 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003095 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003096 break;
3097
3098 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003099 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3100 chan->remote_tx_win = rfc.txwin_size;
3101 else
3102 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3103
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003104 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003105
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003106 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
3107 chan->conn->mtu -
3108 L2CAP_EXT_HDR_SIZE -
3109 L2CAP_SDULEN_SIZE -
3110 L2CAP_FCS_SIZE);
3111 rfc.max_pdu_size = cpu_to_le16(size);
3112 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003113
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003114 rfc.retrans_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003115 __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003116 rfc.monitor_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003117 __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003118
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003119 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003120
3121 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3122 sizeof(rfc), (unsigned long) &rfc);
3123
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003124 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3125 chan->remote_id = efs.id;
3126 chan->remote_stype = efs.stype;
3127 chan->remote_msdu = le16_to_cpu(efs.msdu);
3128 chan->remote_flush_to =
3129 le32_to_cpu(efs.flush_to);
3130 chan->remote_acc_lat =
3131 le32_to_cpu(efs.acc_lat);
3132 chan->remote_sdu_itime =
3133 le32_to_cpu(efs.sdu_itime);
3134 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
3135 sizeof(efs), (unsigned long) &efs);
3136 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003137 break;
3138
3139 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003140 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
3141 chan->conn->mtu -
3142 L2CAP_EXT_HDR_SIZE -
3143 L2CAP_SDULEN_SIZE -
3144 L2CAP_FCS_SIZE);
3145 rfc.max_pdu_size = cpu_to_le16(size);
3146 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003147
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003148 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003149
3150 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3151 sizeof(rfc), (unsigned long) &rfc);
3152
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003153 break;
3154
3155 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003156 result = L2CAP_CONF_UNACCEPT;
3157
3158 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003159 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003160 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003161
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003162 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003163 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003164 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003165 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003166 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003167 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003168
3169 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003170}
3171
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003172static 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 -03003173{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003174 struct l2cap_conf_req *req = data;
3175 void *ptr = req->data;
3176 int type, olen;
3177 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003178 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003179 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003180
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003181 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003182
3183 while (len >= L2CAP_CONF_OPT_SIZE) {
3184 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3185
3186 switch (type) {
3187 case L2CAP_CONF_MTU:
3188 if (val < L2CAP_DEFAULT_MIN_MTU) {
3189 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003190 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003191 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003192 chan->imtu = val;
3193 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003194 break;
3195
3196 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003197 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003198 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003199 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003200 break;
3201
3202 case L2CAP_CONF_RFC:
3203 if (olen == sizeof(rfc))
3204 memcpy(&rfc, (void *)val, olen);
3205
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003206 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003207 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003208 return -ECONNREFUSED;
3209
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003210 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003211
3212 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3213 sizeof(rfc), (unsigned long) &rfc);
3214 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003215
3216 case L2CAP_CONF_EWS:
3217 chan->tx_win = min_t(u16, val,
3218 L2CAP_DEFAULT_EXT_WINDOW);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003219 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
3220 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003221 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003222
3223 case L2CAP_CONF_EFS:
3224 if (olen == sizeof(efs))
3225 memcpy(&efs, (void *)val, olen);
3226
3227 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
3228 efs.stype != L2CAP_SERV_NOTRAFIC &&
3229 efs.stype != chan->local_stype)
3230 return -ECONNREFUSED;
3231
3232 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
3233 sizeof(efs), (unsigned long) &efs);
3234 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003235 }
3236 }
3237
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003238 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003239 return -ECONNREFUSED;
3240
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003241 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003242
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003243 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003244 switch (rfc.mode) {
3245 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003246 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3247 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3248 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003249
3250 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3251 chan->local_msdu = le16_to_cpu(efs.msdu);
3252 chan->local_sdu_itime =
3253 le32_to_cpu(efs.sdu_itime);
3254 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3255 chan->local_flush_to =
3256 le32_to_cpu(efs.flush_to);
3257 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003258 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003259
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003260 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003261 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003262 }
3263 }
3264
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003265 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003266 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003267
3268 return ptr - data;
3269}
3270
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003271static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003272{
3273 struct l2cap_conf_rsp *rsp = data;
3274 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003275
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003276 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003277
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003278 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003279 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003280 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003281
3282 return ptr - data;
3283}
3284
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003285void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003286{
3287 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003288 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003289 u8 buf[128];
3290
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003291 rsp.scid = cpu_to_le16(chan->dcid);
3292 rsp.dcid = cpu_to_le16(chan->scid);
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003293 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
3294 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
3295 l2cap_send_cmd(conn, chan->ident,
3296 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
3297
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003298 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003299 return;
3300
Gustavo F. Padovan710f9b0a2011-03-25 14:30:37 -03003301 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3302 l2cap_build_conf_req(chan, buf), buf);
3303 chan->num_conf_req++;
3304}
3305
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003306static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003307{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003308 int type, olen;
3309 unsigned long val;
3310 struct l2cap_conf_rfc rfc;
3311
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003312 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003313
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003314 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003315 return;
3316
3317 while (len >= L2CAP_CONF_OPT_SIZE) {
3318 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3319
3320 switch (type) {
3321 case L2CAP_CONF_RFC:
3322 if (olen == sizeof(rfc))
3323 memcpy(&rfc, (void *)val, olen);
3324 goto done;
3325 }
3326 }
3327
Mat Martineau36e999a2011-12-08 17:23:21 -08003328 /* Use sane default values in case a misbehaving remote device
3329 * did not send an RFC option.
3330 */
3331 rfc.mode = chan->mode;
3332 rfc.retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3333 rfc.monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3334 rfc.max_pdu_size = cpu_to_le16(chan->imtu);
3335
3336 BT_ERR("Expected RFC option was not found, using defaults");
3337
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003338done:
3339 switch (rfc.mode) {
3340 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003341 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3342 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3343 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003344 break;
3345 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003346 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003347 }
3348}
3349
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003350static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3351{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003352 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003353
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003354 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003355 return 0;
3356
3357 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
3358 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003359 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003360
3361 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003362 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003363
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003364 l2cap_conn_start(conn);
3365 }
3366
3367 return 0;
3368}
3369
Linus Torvalds1da177e2005-04-16 15:20:36 -07003370static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3371{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003372 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3373 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003374 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003375 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003376 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003377
3378 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003379 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003380
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003381 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003382
3383 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003384 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003385 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003386 result = L2CAP_CR_BAD_PSM;
3387 goto sendresp;
3388 }
3389
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003390 parent = pchan->sk;
3391
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003392 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003393 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003394
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003395 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003396 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003397 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003398 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003399 result = L2CAP_CR_SEC_BLOCK;
3400 goto response;
3401 }
3402
Linus Torvalds1da177e2005-04-16 15:20:36 -07003403 result = L2CAP_CR_NO_MEM;
3404
3405 /* Check for backlog size */
3406 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003407 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003408 goto response;
3409 }
3410
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003411 chan = pchan->ops->new_connection(pchan->data);
3412 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003413 goto response;
3414
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003415 sk = chan->sk;
3416
Linus Torvalds1da177e2005-04-16 15:20:36 -07003417 /* Check if we already have channel with that dcid */
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003418 if (__l2cap_get_chan_by_dcid(conn, scid)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003419 sock_set_flag(sk, SOCK_ZAPPED);
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -03003420 chan->ops->close(chan->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003421 goto response;
3422 }
3423
3424 hci_conn_hold(conn->hcon);
3425
Linus Torvalds1da177e2005-04-16 15:20:36 -07003426 bacpy(&bt_sk(sk)->src, conn->src);
3427 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003428 chan->psm = psm;
3429 chan->dcid = scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003430
Gustavo F. Padovand1010242011-03-25 00:39:48 -03003431 bt_accept_enqueue(parent, sk);
3432
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003433 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003434
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003435 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003436
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003437 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003438
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003439 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003440
Marcel Holtmann984947d2009-02-06 23:35:19 +01003441 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003442 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003443 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003444 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003445 result = L2CAP_CR_PEND;
3446 status = L2CAP_CS_AUTHOR_PEND;
3447 parent->sk_data_ready(parent, 0);
3448 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003449 __l2cap_state_change(chan, BT_CONFIG);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003450 result = L2CAP_CR_SUCCESS;
3451 status = L2CAP_CS_NO_INFO;
3452 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003453 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003454 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003455 result = L2CAP_CR_PEND;
3456 status = L2CAP_CS_AUTHEN_PEND;
3457 }
3458 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003459 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003460 result = L2CAP_CR_PEND;
3461 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003462 }
3463
Linus Torvalds1da177e2005-04-16 15:20:36 -07003464response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003465 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003466 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003467
3468sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003469 rsp.scid = cpu_to_le16(scid);
3470 rsp.dcid = cpu_to_le16(dcid);
3471 rsp.result = cpu_to_le16(result);
3472 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003473 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003474
3475 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3476 struct l2cap_info_req info;
3477 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3478
3479 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3480 conn->info_ident = l2cap_get_ident(conn);
3481
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003482 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003483
3484 l2cap_send_cmd(conn, conn->info_ident,
3485 L2CAP_INFO_REQ, sizeof(info), &info);
3486 }
3487
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003488 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003489 result == L2CAP_CR_SUCCESS) {
3490 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003491 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003492 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003493 l2cap_build_conf_req(chan, buf), buf);
3494 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003495 }
3496
Linus Torvalds1da177e2005-04-16 15:20:36 -07003497 return 0;
3498}
3499
3500static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3501{
3502 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3503 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003504 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003505 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003506 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003507
3508 scid = __le16_to_cpu(rsp->scid);
3509 dcid = __le16_to_cpu(rsp->dcid);
3510 result = __le16_to_cpu(rsp->result);
3511 status = __le16_to_cpu(rsp->status);
3512
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003513 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x",
3514 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003515
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003516 mutex_lock(&conn->chan_lock);
3517
Linus Torvalds1da177e2005-04-16 15:20:36 -07003518 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003519 chan = __l2cap_get_chan_by_scid(conn, scid);
3520 if (!chan) {
3521 err = -EFAULT;
3522 goto unlock;
3523 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003524 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003525 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3526 if (!chan) {
3527 err = -EFAULT;
3528 goto unlock;
3529 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003530 }
3531
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003532 err = 0;
3533
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003534 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003535
Linus Torvalds1da177e2005-04-16 15:20:36 -07003536 switch (result) {
3537 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003538 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003539 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003540 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003541 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003542
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003543 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003544 break;
3545
Linus Torvalds1da177e2005-04-16 15:20:36 -07003546 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003547 l2cap_build_conf_req(chan, req), req);
3548 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003549 break;
3550
3551 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003552 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003553 break;
3554
3555 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003556 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003557 break;
3558 }
3559
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003560 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003561
3562unlock:
3563 mutex_unlock(&conn->chan_lock);
3564
3565 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003566}
3567
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003568static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003569{
3570 /* FCS is enabled only in ERTM or streaming mode, if one or both
3571 * sides request it.
3572 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003573 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003574 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003575 else if (!test_bit(CONF_NO_FCS_RECV, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003576 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003577}
3578
Al Viro88219a02007-07-29 00:17:25 -07003579static 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 -07003580{
3581 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3582 u16 dcid, flags;
3583 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003584 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003585 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003586
3587 dcid = __le16_to_cpu(req->dcid);
3588 flags = __le16_to_cpu(req->flags);
3589
3590 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3591
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003592 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003593 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003594 return -ENOENT;
3595
David S. Miller033b1142011-07-21 13:38:42 -07003596 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003597 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003598
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003599 rej.reason = cpu_to_le16(L2CAP_REJ_INVALID_CID);
3600 rej.scid = cpu_to_le16(chan->scid);
3601 rej.dcid = cpu_to_le16(chan->dcid);
3602
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003603 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
3604 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003605 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003606 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003607
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003608 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003609 len = cmd_len - sizeof(*req);
Dan Rosenberg7ac28812011-06-24 08:38:05 -04003610 if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003611 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003612 l2cap_build_conf_rsp(chan, rsp,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003613 L2CAP_CONF_REJECT, flags), rsp);
3614 goto unlock;
3615 }
3616
3617 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003618 memcpy(chan->conf_req + chan->conf_len, req->data, len);
3619 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003620
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003621 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003622 /* Incomplete config. Send empty response. */
3623 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003624 l2cap_build_conf_rsp(chan, rsp,
Andrei Emeltchenko5325e5b2012-05-23 11:31:22 +03003625 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003626 goto unlock;
3627 }
3628
3629 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003630 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003631 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003632 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003633 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003634 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003635
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003636 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003637 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003638
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003639 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003640 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003641
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003642 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02003643 goto unlock;
3644
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003645 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003646 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003647
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003648 l2cap_state_change(chan, BT_CONNECTED);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003649
Mat Martineau105bdf92012-04-27 16:50:48 -07003650 if (chan->mode == L2CAP_MODE_ERTM ||
3651 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003652 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003653
Mat Martineau3c588192012-04-11 10:48:42 -07003654 if (err < 0)
3655 l2cap_send_disconn_req(chan->conn, chan, -err);
3656 else
3657 l2cap_chan_ready(chan);
3658
Marcel Holtmann876d9482007-10-20 13:35:42 +02003659 goto unlock;
3660 }
3661
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003662 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003663 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003664 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003665 l2cap_build_conf_req(chan, buf), buf);
3666 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003667 }
3668
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003669 /* Got Conf Rsp PENDING from remote side and asume we sent
3670 Conf Rsp PENDING in the code above */
3671 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
3672 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3673
3674 /* check compatibility */
3675
3676 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3677 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3678
3679 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003680 l2cap_build_conf_rsp(chan, rsp,
Andrei Emeltchenko5325e5b2012-05-23 11:31:22 +03003681 L2CAP_CONF_SUCCESS, flags), rsp);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003682 }
3683
Linus Torvalds1da177e2005-04-16 15:20:36 -07003684unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003685 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003686 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003687}
3688
3689static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3690{
3691 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3692 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003693 struct l2cap_chan *chan;
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003694 int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07003695 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003696
3697 scid = __le16_to_cpu(rsp->scid);
3698 flags = __le16_to_cpu(rsp->flags);
3699 result = __le16_to_cpu(rsp->result);
3700
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003701 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
3702 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003703
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003704 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003705 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003706 return 0;
3707
3708 switch (result) {
3709 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003710 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003711 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003712 break;
3713
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003714 case L2CAP_CONF_PENDING:
3715 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
3716
3717 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3718 char buf[64];
3719
3720 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3721 buf, &result);
3722 if (len < 0) {
3723 l2cap_send_disconn_req(conn, chan, ECONNRESET);
3724 goto done;
3725 }
3726
3727 /* check compatibility */
3728
3729 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3730 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3731
3732 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003733 l2cap_build_conf_rsp(chan, buf,
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003734 L2CAP_CONF_SUCCESS, 0x0000), buf);
3735 }
3736 goto done;
3737
Linus Torvalds1da177e2005-04-16 15:20:36 -07003738 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003739 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003740 char req[64];
3741
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003742 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003743 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003744 goto done;
3745 }
3746
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003747 /* throw out any old stored conf requests */
3748 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003749 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3750 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003751 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003752 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003753 goto done;
3754 }
3755
3756 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3757 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003758 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003759 if (result != L2CAP_CONF_SUCCESS)
3760 goto done;
3761 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003762 }
3763
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003764 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003765 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02003766
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003767 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003768 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003769 goto done;
3770 }
3771
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003772 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003773 goto done;
3774
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003775 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003776
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003777 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003778 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003779
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003780 l2cap_state_change(chan, BT_CONNECTED);
Mat Martineau105bdf92012-04-27 16:50:48 -07003781 if (chan->mode == L2CAP_MODE_ERTM ||
3782 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003783 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003784
Mat Martineau3c588192012-04-11 10:48:42 -07003785 if (err < 0)
3786 l2cap_send_disconn_req(chan->conn, chan, -err);
3787 else
3788 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003789 }
3790
3791done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003792 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003793 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003794}
3795
3796static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3797{
3798 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3799 struct l2cap_disconn_rsp rsp;
3800 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003801 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003802 struct sock *sk;
3803
3804 scid = __le16_to_cpu(req->scid);
3805 dcid = __le16_to_cpu(req->dcid);
3806
3807 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3808
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003809 mutex_lock(&conn->chan_lock);
3810
3811 chan = __l2cap_get_chan_by_scid(conn, dcid);
3812 if (!chan) {
3813 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003814 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003815 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003816
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003817 l2cap_chan_lock(chan);
3818
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003819 sk = chan->sk;
3820
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003821 rsp.dcid = cpu_to_le16(chan->scid);
3822 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003823 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3824
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003825 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003826 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003827 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003828
Mat Martineau61d6ef32012-04-27 16:50:50 -07003829 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003830 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003831
3832 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003833
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -03003834 chan->ops->close(chan->data);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003835 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003836
3837 mutex_unlock(&conn->chan_lock);
3838
Linus Torvalds1da177e2005-04-16 15:20:36 -07003839 return 0;
3840}
3841
3842static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3843{
3844 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3845 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003846 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003847
3848 scid = __le16_to_cpu(rsp->scid);
3849 dcid = __le16_to_cpu(rsp->dcid);
3850
3851 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3852
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003853 mutex_lock(&conn->chan_lock);
3854
3855 chan = __l2cap_get_chan_by_scid(conn, scid);
3856 if (!chan) {
3857 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003858 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003859 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003860
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003861 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003862
Mat Martineau61d6ef32012-04-27 16:50:50 -07003863 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003864 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003865
3866 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003867
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -03003868 chan->ops->close(chan->data);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003869 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003870
3871 mutex_unlock(&conn->chan_lock);
3872
Linus Torvalds1da177e2005-04-16 15:20:36 -07003873 return 0;
3874}
3875
3876static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3877{
3878 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003879 u16 type;
3880
3881 type = __le16_to_cpu(req->type);
3882
3883 BT_DBG("type 0x%4.4x", type);
3884
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003885 if (type == L2CAP_IT_FEAT_MASK) {
3886 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003887 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003888 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3889 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3890 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03003891 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003892 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3893 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003894 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003895 feat_mask |= L2CAP_FEAT_EXT_FLOW
3896 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003897
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003898 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003899 l2cap_send_cmd(conn, cmd->ident,
3900 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003901 } else if (type == L2CAP_IT_FIXED_CHAN) {
3902 u8 buf[12];
3903 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07003904
3905 if (enable_hs)
3906 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
3907 else
3908 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
3909
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003910 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3911 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03003912 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003913 l2cap_send_cmd(conn, cmd->ident,
3914 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003915 } else {
3916 struct l2cap_info_rsp rsp;
3917 rsp.type = cpu_to_le16(type);
3918 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3919 l2cap_send_cmd(conn, cmd->ident,
3920 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3921 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003922
3923 return 0;
3924}
3925
3926static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3927{
3928 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3929 u16 type, result;
3930
3931 type = __le16_to_cpu(rsp->type);
3932 result = __le16_to_cpu(rsp->result);
3933
3934 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3935
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02003936 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
3937 if (cmd->ident != conn->info_ident ||
3938 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
3939 return 0;
3940
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003941 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003942
Ville Tervoadb08ed2010-08-04 09:43:33 +03003943 if (result != L2CAP_IR_SUCCESS) {
3944 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3945 conn->info_ident = 0;
3946
3947 l2cap_conn_start(conn);
3948
3949 return 0;
3950 }
3951
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003952 switch (type) {
3953 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07003954 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003955
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003956 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003957 struct l2cap_info_req req;
3958 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3959
3960 conn->info_ident = l2cap_get_ident(conn);
3961
3962 l2cap_send_cmd(conn, conn->info_ident,
3963 L2CAP_INFO_REQ, sizeof(req), &req);
3964 } else {
3965 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3966 conn->info_ident = 0;
3967
3968 l2cap_conn_start(conn);
3969 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003970 break;
3971
3972 case L2CAP_IT_FIXED_CHAN:
3973 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01003974 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003975 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003976
3977 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003978 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003979 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003980
Linus Torvalds1da177e2005-04-16 15:20:36 -07003981 return 0;
3982}
3983
Mat Martineauf94ff6f2011-11-02 16:18:32 -07003984static inline int l2cap_create_channel_req(struct l2cap_conn *conn,
3985 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3986 void *data)
3987{
3988 struct l2cap_create_chan_req *req = data;
3989 struct l2cap_create_chan_rsp rsp;
3990 u16 psm, scid;
3991
3992 if (cmd_len != sizeof(*req))
3993 return -EPROTO;
3994
3995 if (!enable_hs)
3996 return -EINVAL;
3997
3998 psm = le16_to_cpu(req->psm);
3999 scid = le16_to_cpu(req->scid);
4000
4001 BT_DBG("psm %d, scid %d, amp_id %d", psm, scid, req->amp_id);
4002
4003 /* Placeholder: Always reject */
4004 rsp.dcid = 0;
4005 rsp.scid = cpu_to_le16(scid);
Andrei Emeltchenko8ce0c492012-03-12 12:13:09 +02004006 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4007 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004008
4009 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4010 sizeof(rsp), &rsp);
4011
4012 return 0;
4013}
4014
4015static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn,
4016 struct l2cap_cmd_hdr *cmd, void *data)
4017{
4018 BT_DBG("conn %p", conn);
4019
4020 return l2cap_connect_rsp(conn, cmd, data);
4021}
4022
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004023static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident,
4024 u16 icid, u16 result)
4025{
4026 struct l2cap_move_chan_rsp rsp;
4027
4028 BT_DBG("icid %d, result %d", icid, result);
4029
4030 rsp.icid = cpu_to_le16(icid);
4031 rsp.result = cpu_to_le16(result);
4032
4033 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_RSP, sizeof(rsp), &rsp);
4034}
4035
4036static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn,
4037 struct l2cap_chan *chan, u16 icid, u16 result)
4038{
4039 struct l2cap_move_chan_cfm cfm;
4040 u8 ident;
4041
4042 BT_DBG("icid %d, result %d", icid, result);
4043
4044 ident = l2cap_get_ident(conn);
4045 if (chan)
4046 chan->ident = ident;
4047
4048 cfm.icid = cpu_to_le16(icid);
4049 cfm.result = cpu_to_le16(result);
4050
4051 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM, sizeof(cfm), &cfm);
4052}
4053
4054static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
4055 u16 icid)
4056{
4057 struct l2cap_move_chan_cfm_rsp rsp;
4058
4059 BT_DBG("icid %d", icid);
4060
4061 rsp.icid = cpu_to_le16(icid);
4062 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4063}
4064
4065static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
4066 struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data)
4067{
4068 struct l2cap_move_chan_req *req = data;
4069 u16 icid = 0;
4070 u16 result = L2CAP_MR_NOT_ALLOWED;
4071
4072 if (cmd_len != sizeof(*req))
4073 return -EPROTO;
4074
4075 icid = le16_to_cpu(req->icid);
4076
4077 BT_DBG("icid %d, dest_amp_id %d", icid, req->dest_amp_id);
4078
4079 if (!enable_hs)
4080 return -EINVAL;
4081
4082 /* Placeholder: Always refuse */
4083 l2cap_send_move_chan_rsp(conn, cmd->ident, icid, result);
4084
4085 return 0;
4086}
4087
4088static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn,
4089 struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data)
4090{
4091 struct l2cap_move_chan_rsp *rsp = data;
4092 u16 icid, result;
4093
4094 if (cmd_len != sizeof(*rsp))
4095 return -EPROTO;
4096
4097 icid = le16_to_cpu(rsp->icid);
4098 result = le16_to_cpu(rsp->result);
4099
4100 BT_DBG("icid %d, result %d", icid, result);
4101
4102 /* Placeholder: Always unconfirmed */
4103 l2cap_send_move_chan_cfm(conn, NULL, icid, L2CAP_MC_UNCONFIRMED);
4104
4105 return 0;
4106}
4107
4108static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn,
4109 struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data)
4110{
4111 struct l2cap_move_chan_cfm *cfm = data;
4112 u16 icid, result;
4113
4114 if (cmd_len != sizeof(*cfm))
4115 return -EPROTO;
4116
4117 icid = le16_to_cpu(cfm->icid);
4118 result = le16_to_cpu(cfm->result);
4119
4120 BT_DBG("icid %d, result %d", icid, result);
4121
4122 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4123
4124 return 0;
4125}
4126
4127static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
4128 struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data)
4129{
4130 struct l2cap_move_chan_cfm_rsp *rsp = data;
4131 u16 icid;
4132
4133 if (cmd_len != sizeof(*rsp))
4134 return -EPROTO;
4135
4136 icid = le16_to_cpu(rsp->icid);
4137
4138 BT_DBG("icid %d", icid);
4139
4140 return 0;
4141}
4142
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004143static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Claudio Takahaside731152011-02-11 19:28:55 -02004144 u16 to_multiplier)
4145{
4146 u16 max_latency;
4147
4148 if (min > max || min < 6 || max > 3200)
4149 return -EINVAL;
4150
4151 if (to_multiplier < 10 || to_multiplier > 3200)
4152 return -EINVAL;
4153
4154 if (max >= to_multiplier * 8)
4155 return -EINVAL;
4156
4157 max_latency = (to_multiplier * 8 / max) - 1;
4158 if (latency > 499 || latency > max_latency)
4159 return -EINVAL;
4160
4161 return 0;
4162}
4163
4164static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
4165 struct l2cap_cmd_hdr *cmd, u8 *data)
4166{
4167 struct hci_conn *hcon = conn->hcon;
4168 struct l2cap_conn_param_update_req *req;
4169 struct l2cap_conn_param_update_rsp rsp;
4170 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004171 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02004172
4173 if (!(hcon->link_mode & HCI_LM_MASTER))
4174 return -EINVAL;
4175
4176 cmd_len = __le16_to_cpu(cmd->len);
4177 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
4178 return -EPROTO;
4179
4180 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004181 min = __le16_to_cpu(req->min);
4182 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02004183 latency = __le16_to_cpu(req->latency);
4184 to_multiplier = __le16_to_cpu(req->to_multiplier);
4185
4186 BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
4187 min, max, latency, to_multiplier);
4188
4189 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004190
4191 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
4192 if (err)
Claudio Takahaside731152011-02-11 19:28:55 -02004193 rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
4194 else
4195 rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
4196
4197 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
4198 sizeof(rsp), &rsp);
4199
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004200 if (!err)
4201 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
4202
Claudio Takahaside731152011-02-11 19:28:55 -02004203 return 0;
4204}
4205
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004206static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
4207 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
4208{
4209 int err = 0;
4210
4211 switch (cmd->code) {
4212 case L2CAP_COMMAND_REJ:
4213 l2cap_command_rej(conn, cmd, data);
4214 break;
4215
4216 case L2CAP_CONN_REQ:
4217 err = l2cap_connect_req(conn, cmd, data);
4218 break;
4219
4220 case L2CAP_CONN_RSP:
4221 err = l2cap_connect_rsp(conn, cmd, data);
4222 break;
4223
4224 case L2CAP_CONF_REQ:
4225 err = l2cap_config_req(conn, cmd, cmd_len, data);
4226 break;
4227
4228 case L2CAP_CONF_RSP:
4229 err = l2cap_config_rsp(conn, cmd, data);
4230 break;
4231
4232 case L2CAP_DISCONN_REQ:
4233 err = l2cap_disconnect_req(conn, cmd, data);
4234 break;
4235
4236 case L2CAP_DISCONN_RSP:
4237 err = l2cap_disconnect_rsp(conn, cmd, data);
4238 break;
4239
4240 case L2CAP_ECHO_REQ:
4241 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
4242 break;
4243
4244 case L2CAP_ECHO_RSP:
4245 break;
4246
4247 case L2CAP_INFO_REQ:
4248 err = l2cap_information_req(conn, cmd, data);
4249 break;
4250
4251 case L2CAP_INFO_RSP:
4252 err = l2cap_information_rsp(conn, cmd, data);
4253 break;
4254
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004255 case L2CAP_CREATE_CHAN_REQ:
4256 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
4257 break;
4258
4259 case L2CAP_CREATE_CHAN_RSP:
4260 err = l2cap_create_channel_rsp(conn, cmd, data);
4261 break;
4262
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004263 case L2CAP_MOVE_CHAN_REQ:
4264 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
4265 break;
4266
4267 case L2CAP_MOVE_CHAN_RSP:
4268 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
4269 break;
4270
4271 case L2CAP_MOVE_CHAN_CFM:
4272 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
4273 break;
4274
4275 case L2CAP_MOVE_CHAN_CFM_RSP:
4276 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
4277 break;
4278
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004279 default:
4280 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
4281 err = -EINVAL;
4282 break;
4283 }
4284
4285 return err;
4286}
4287
4288static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
4289 struct l2cap_cmd_hdr *cmd, u8 *data)
4290{
4291 switch (cmd->code) {
4292 case L2CAP_COMMAND_REJ:
4293 return 0;
4294
4295 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02004296 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004297
4298 case L2CAP_CONN_PARAM_UPDATE_RSP:
4299 return 0;
4300
4301 default:
4302 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
4303 return -EINVAL;
4304 }
4305}
4306
4307static inline void l2cap_sig_channel(struct l2cap_conn *conn,
4308 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004309{
4310 u8 *data = skb->data;
4311 int len = skb->len;
4312 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004313 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004314
4315 l2cap_raw_recv(conn, skb);
4316
4317 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07004318 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004319 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
4320 data += L2CAP_CMD_HDR_SIZE;
4321 len -= L2CAP_CMD_HDR_SIZE;
4322
Al Viro88219a02007-07-29 00:17:25 -07004323 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004324
Al Viro88219a02007-07-29 00:17:25 -07004325 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 -07004326
Al Viro88219a02007-07-29 00:17:25 -07004327 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004328 BT_DBG("corrupted command");
4329 break;
4330 }
4331
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004332 if (conn->hcon->type == LE_LINK)
4333 err = l2cap_le_sig_cmd(conn, &cmd, data);
4334 else
4335 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004336
4337 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004338 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03004339
4340 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004341
4342 /* FIXME: Map err to a valid reason */
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004343 rej.reason = cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004344 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
4345 }
4346
Al Viro88219a02007-07-29 00:17:25 -07004347 data += cmd_len;
4348 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004349 }
4350
4351 kfree_skb(skb);
4352}
4353
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004354static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004355{
4356 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03004357 int hdr_size;
4358
4359 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
4360 hdr_size = L2CAP_EXT_HDR_SIZE;
4361 else
4362 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004363
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004364 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004365 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004366 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
4367 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
4368
4369 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03004370 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004371 }
4372 return 0;
4373}
4374
Mat Martineau6ea00482012-05-17 20:53:52 -07004375static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004376{
Mat Martineaue31f7632012-05-17 20:53:41 -07004377 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004378
Mat Martineaue31f7632012-05-17 20:53:41 -07004379 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004380
Mat Martineaue31f7632012-05-17 20:53:41 -07004381 memset(&control, 0, sizeof(control));
4382 control.sframe = 1;
4383 control.final = 1;
4384 control.reqseq = chan->buffer_seq;
4385 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004386
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004387 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07004388 control.super = L2CAP_SUPER_RNR;
4389 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004390 }
4391
Mat Martineaue31f7632012-05-17 20:53:41 -07004392 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
4393 chan->unacked_frames > 0)
4394 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004395
Mat Martineaue31f7632012-05-17 20:53:41 -07004396 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03004397 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004398
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004399 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07004400 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
4401 /* F-bit wasn't sent in an s-frame or i-frame yet, so
4402 * send it now.
4403 */
4404 control.super = L2CAP_SUPER_RR;
4405 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004406 }
4407}
4408
Mat Martineau84084a32011-07-22 14:54:00 -07004409static void append_skb_frag(struct sk_buff *skb,
4410 struct sk_buff *new_frag, struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004411{
Mat Martineau84084a32011-07-22 14:54:00 -07004412 /* skb->len reflects data in skb as well as all fragments
4413 * skb->data_len reflects only data in fragments
4414 */
4415 if (!skb_has_frag_list(skb))
4416 skb_shinfo(skb)->frag_list = new_frag;
4417
4418 new_frag->next = NULL;
4419
4420 (*last_frag)->next = new_frag;
4421 *last_frag = new_frag;
4422
4423 skb->len += new_frag->len;
4424 skb->data_len += new_frag->len;
4425 skb->truesize += new_frag->truesize;
4426}
4427
Mat Martineau4b51dae92012-05-17 20:53:37 -07004428static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
4429 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07004430{
4431 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004432
Mat Martineau4b51dae92012-05-17 20:53:37 -07004433 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004434 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07004435 if (chan->sdu)
4436 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004437
Mat Martineau84084a32011-07-22 14:54:00 -07004438 err = chan->ops->recv(chan->data, skb);
4439 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004440
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004441 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07004442 if (chan->sdu)
4443 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004444
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004445 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004446 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004447
Mat Martineau84084a32011-07-22 14:54:00 -07004448 if (chan->sdu_len > chan->imtu) {
4449 err = -EMSGSIZE;
4450 break;
4451 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004452
Mat Martineau84084a32011-07-22 14:54:00 -07004453 if (skb->len >= chan->sdu_len)
4454 break;
4455
4456 chan->sdu = skb;
4457 chan->sdu_last_frag = skb;
4458
4459 skb = NULL;
4460 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004461 break;
4462
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004463 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004464 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004465 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004466
Mat Martineau84084a32011-07-22 14:54:00 -07004467 append_skb_frag(chan->sdu, skb,
4468 &chan->sdu_last_frag);
4469 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004470
Mat Martineau84084a32011-07-22 14:54:00 -07004471 if (chan->sdu->len >= chan->sdu_len)
4472 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004473
Mat Martineau84084a32011-07-22 14:54:00 -07004474 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004475 break;
4476
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004477 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004478 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004479 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004480
Mat Martineau84084a32011-07-22 14:54:00 -07004481 append_skb_frag(chan->sdu, skb,
4482 &chan->sdu_last_frag);
4483 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004484
Mat Martineau84084a32011-07-22 14:54:00 -07004485 if (chan->sdu->len != chan->sdu_len)
4486 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004487
Mat Martineau84084a32011-07-22 14:54:00 -07004488 err = chan->ops->recv(chan->data, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004489
Mat Martineau84084a32011-07-22 14:54:00 -07004490 if (!err) {
4491 /* Reassembly complete */
4492 chan->sdu = NULL;
4493 chan->sdu_last_frag = NULL;
4494 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004495 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004496 break;
4497 }
4498
Mat Martineau84084a32011-07-22 14:54:00 -07004499 if (err) {
4500 kfree_skb(skb);
4501 kfree_skb(chan->sdu);
4502 chan->sdu = NULL;
4503 chan->sdu_last_frag = NULL;
4504 chan->sdu_len = 0;
4505 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004506
Mat Martineau84084a32011-07-22 14:54:00 -07004507 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004508}
4509
Mat Martineaue3281402011-07-07 09:39:02 -07004510void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03004511{
Mat Martineau61aa4f52012-05-17 20:53:40 -07004512 u8 event;
4513
4514 if (chan->mode != L2CAP_MODE_ERTM)
4515 return;
4516
4517 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03004518 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004519}
4520
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004521static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
4522{
Mat Martineau63838722012-05-17 20:53:45 -07004523 int err = 0;
4524 /* Pass sequential frames to l2cap_reassemble_sdu()
4525 * until a gap is encountered.
4526 */
4527
4528 BT_DBG("chan %p", chan);
4529
4530 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4531 struct sk_buff *skb;
4532 BT_DBG("Searching for skb with txseq %d (queue len %d)",
4533 chan->buffer_seq, skb_queue_len(&chan->srej_q));
4534
4535 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
4536
4537 if (!skb)
4538 break;
4539
4540 skb_unlink(skb, &chan->srej_q);
4541 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
4542 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
4543 if (err)
4544 break;
4545 }
4546
4547 if (skb_queue_empty(&chan->srej_q)) {
4548 chan->rx_state = L2CAP_RX_STATE_RECV;
4549 l2cap_send_ack(chan);
4550 }
4551
4552 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004553}
4554
4555static void l2cap_handle_srej(struct l2cap_chan *chan,
4556 struct l2cap_ctrl *control)
4557{
Mat Martineauf80842a2012-05-17 20:53:46 -07004558 struct sk_buff *skb;
4559
4560 BT_DBG("chan %p, control %p", chan, control);
4561
4562 if (control->reqseq == chan->next_tx_seq) {
4563 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4564 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4565 return;
4566 }
4567
4568 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4569
4570 if (skb == NULL) {
4571 BT_DBG("Seq %d not available for retransmission",
4572 control->reqseq);
4573 return;
4574 }
4575
4576 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
4577 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4578 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4579 return;
4580 }
4581
4582 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4583
4584 if (control->poll) {
4585 l2cap_pass_to_tx(chan, control);
4586
4587 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4588 l2cap_retransmit(chan, control);
4589 l2cap_ertm_send(chan);
4590
4591 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4592 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4593 chan->srej_save_reqseq = control->reqseq;
4594 }
4595 } else {
4596 l2cap_pass_to_tx_fbit(chan, control);
4597
4598 if (control->final) {
4599 if (chan->srej_save_reqseq != control->reqseq ||
4600 !test_and_clear_bit(CONN_SREJ_ACT,
4601 &chan->conn_state))
4602 l2cap_retransmit(chan, control);
4603 } else {
4604 l2cap_retransmit(chan, control);
4605 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4606 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4607 chan->srej_save_reqseq = control->reqseq;
4608 }
4609 }
4610 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004611}
4612
4613static void l2cap_handle_rej(struct l2cap_chan *chan,
4614 struct l2cap_ctrl *control)
4615{
Mat Martineaufcd289d2012-05-17 20:53:47 -07004616 struct sk_buff *skb;
4617
4618 BT_DBG("chan %p, control %p", chan, control);
4619
4620 if (control->reqseq == chan->next_tx_seq) {
4621 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4622 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4623 return;
4624 }
4625
4626 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4627
4628 if (chan->max_tx && skb &&
4629 bt_cb(skb)->control.retries >= chan->max_tx) {
4630 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4631 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4632 return;
4633 }
4634
4635 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4636
4637 l2cap_pass_to_tx(chan, control);
4638
4639 if (control->final) {
4640 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
4641 l2cap_retransmit_all(chan, control);
4642 } else {
4643 l2cap_retransmit_all(chan, control);
4644 l2cap_ertm_send(chan);
4645 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
4646 set_bit(CONN_REJ_ACT, &chan->conn_state);
4647 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004648}
4649
Mat Martineau4b51dae92012-05-17 20:53:37 -07004650static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
4651{
4652 BT_DBG("chan %p, txseq %d", chan, txseq);
4653
4654 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
4655 chan->expected_tx_seq);
4656
4657 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
4658 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4659 chan->tx_win) {
4660 /* See notes below regarding "double poll" and
4661 * invalid packets.
4662 */
4663 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4664 BT_DBG("Invalid/Ignore - after SREJ");
4665 return L2CAP_TXSEQ_INVALID_IGNORE;
4666 } else {
4667 BT_DBG("Invalid - in window after SREJ sent");
4668 return L2CAP_TXSEQ_INVALID;
4669 }
4670 }
4671
4672 if (chan->srej_list.head == txseq) {
4673 BT_DBG("Expected SREJ");
4674 return L2CAP_TXSEQ_EXPECTED_SREJ;
4675 }
4676
4677 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
4678 BT_DBG("Duplicate SREJ - txseq already stored");
4679 return L2CAP_TXSEQ_DUPLICATE_SREJ;
4680 }
4681
4682 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
4683 BT_DBG("Unexpected SREJ - not requested");
4684 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
4685 }
4686 }
4687
4688 if (chan->expected_tx_seq == txseq) {
4689 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4690 chan->tx_win) {
4691 BT_DBG("Invalid - txseq outside tx window");
4692 return L2CAP_TXSEQ_INVALID;
4693 } else {
4694 BT_DBG("Expected");
4695 return L2CAP_TXSEQ_EXPECTED;
4696 }
4697 }
4698
4699 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
4700 __seq_offset(chan, chan->expected_tx_seq,
4701 chan->last_acked_seq)){
4702 BT_DBG("Duplicate - expected_tx_seq later than txseq");
4703 return L2CAP_TXSEQ_DUPLICATE;
4704 }
4705
4706 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
4707 /* A source of invalid packets is a "double poll" condition,
4708 * where delays cause us to send multiple poll packets. If
4709 * the remote stack receives and processes both polls,
4710 * sequence numbers can wrap around in such a way that a
4711 * resent frame has a sequence number that looks like new data
4712 * with a sequence gap. This would trigger an erroneous SREJ
4713 * request.
4714 *
4715 * Fortunately, this is impossible with a tx window that's
4716 * less than half of the maximum sequence number, which allows
4717 * invalid frames to be safely ignored.
4718 *
4719 * With tx window sizes greater than half of the tx window
4720 * maximum, the frame is invalid and cannot be ignored. This
4721 * causes a disconnect.
4722 */
4723
4724 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4725 BT_DBG("Invalid/Ignore - txseq outside tx window");
4726 return L2CAP_TXSEQ_INVALID_IGNORE;
4727 } else {
4728 BT_DBG("Invalid - txseq outside tx window");
4729 return L2CAP_TXSEQ_INVALID;
4730 }
4731 } else {
4732 BT_DBG("Unexpected - txseq indicates missing frames");
4733 return L2CAP_TXSEQ_UNEXPECTED;
4734 }
4735}
4736
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004737static int l2cap_rx_state_recv(struct l2cap_chan *chan,
4738 struct l2cap_ctrl *control,
4739 struct sk_buff *skb, u8 event)
4740{
4741 int err = 0;
4742 bool skb_in_use = 0;
4743
4744 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4745 event);
4746
4747 switch (event) {
4748 case L2CAP_EV_RECV_IFRAME:
4749 switch (l2cap_classify_txseq(chan, control->txseq)) {
4750 case L2CAP_TXSEQ_EXPECTED:
4751 l2cap_pass_to_tx(chan, control);
4752
4753 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4754 BT_DBG("Busy, discarding expected seq %d",
4755 control->txseq);
4756 break;
4757 }
4758
4759 chan->expected_tx_seq = __next_seq(chan,
4760 control->txseq);
4761
4762 chan->buffer_seq = chan->expected_tx_seq;
4763 skb_in_use = 1;
4764
4765 err = l2cap_reassemble_sdu(chan, skb, control);
4766 if (err)
4767 break;
4768
4769 if (control->final) {
4770 if (!test_and_clear_bit(CONN_REJ_ACT,
4771 &chan->conn_state)) {
4772 control->final = 0;
4773 l2cap_retransmit_all(chan, control);
4774 l2cap_ertm_send(chan);
4775 }
4776 }
4777
4778 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
4779 l2cap_send_ack(chan);
4780 break;
4781 case L2CAP_TXSEQ_UNEXPECTED:
4782 l2cap_pass_to_tx(chan, control);
4783
4784 /* Can't issue SREJ frames in the local busy state.
4785 * Drop this frame, it will be seen as missing
4786 * when local busy is exited.
4787 */
4788 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4789 BT_DBG("Busy, discarding unexpected seq %d",
4790 control->txseq);
4791 break;
4792 }
4793
4794 /* There was a gap in the sequence, so an SREJ
4795 * must be sent for each missing frame. The
4796 * current frame is stored for later use.
4797 */
4798 skb_queue_tail(&chan->srej_q, skb);
4799 skb_in_use = 1;
4800 BT_DBG("Queued %p (queue len %d)", skb,
4801 skb_queue_len(&chan->srej_q));
4802
4803 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
4804 l2cap_seq_list_clear(&chan->srej_list);
4805 l2cap_send_srej(chan, control->txseq);
4806
4807 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
4808 break;
4809 case L2CAP_TXSEQ_DUPLICATE:
4810 l2cap_pass_to_tx(chan, control);
4811 break;
4812 case L2CAP_TXSEQ_INVALID_IGNORE:
4813 break;
4814 case L2CAP_TXSEQ_INVALID:
4815 default:
4816 l2cap_send_disconn_req(chan->conn, chan,
4817 ECONNRESET);
4818 break;
4819 }
4820 break;
4821 case L2CAP_EV_RECV_RR:
4822 l2cap_pass_to_tx(chan, control);
4823 if (control->final) {
4824 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4825
4826 if (!test_and_clear_bit(CONN_REJ_ACT,
4827 &chan->conn_state)) {
4828 control->final = 0;
4829 l2cap_retransmit_all(chan, control);
4830 }
4831
4832 l2cap_ertm_send(chan);
4833 } else if (control->poll) {
4834 l2cap_send_i_or_rr_or_rnr(chan);
4835 } else {
4836 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4837 &chan->conn_state) &&
4838 chan->unacked_frames)
4839 __set_retrans_timer(chan);
4840
4841 l2cap_ertm_send(chan);
4842 }
4843 break;
4844 case L2CAP_EV_RECV_RNR:
4845 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4846 l2cap_pass_to_tx(chan, control);
4847 if (control && control->poll) {
4848 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4849 l2cap_send_rr_or_rnr(chan, 0);
4850 }
4851 __clear_retrans_timer(chan);
4852 l2cap_seq_list_clear(&chan->retrans_list);
4853 break;
4854 case L2CAP_EV_RECV_REJ:
4855 l2cap_handle_rej(chan, control);
4856 break;
4857 case L2CAP_EV_RECV_SREJ:
4858 l2cap_handle_srej(chan, control);
4859 break;
4860 default:
4861 break;
4862 }
4863
4864 if (skb && !skb_in_use) {
4865 BT_DBG("Freeing %p", skb);
4866 kfree_skb(skb);
4867 }
4868
4869 return err;
4870}
4871
4872static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
4873 struct l2cap_ctrl *control,
4874 struct sk_buff *skb, u8 event)
4875{
4876 int err = 0;
4877 u16 txseq = control->txseq;
4878 bool skb_in_use = 0;
4879
4880 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4881 event);
4882
4883 switch (event) {
4884 case L2CAP_EV_RECV_IFRAME:
4885 switch (l2cap_classify_txseq(chan, txseq)) {
4886 case L2CAP_TXSEQ_EXPECTED:
4887 /* Keep frame for reassembly later */
4888 l2cap_pass_to_tx(chan, control);
4889 skb_queue_tail(&chan->srej_q, skb);
4890 skb_in_use = 1;
4891 BT_DBG("Queued %p (queue len %d)", skb,
4892 skb_queue_len(&chan->srej_q));
4893
4894 chan->expected_tx_seq = __next_seq(chan, txseq);
4895 break;
4896 case L2CAP_TXSEQ_EXPECTED_SREJ:
4897 l2cap_seq_list_pop(&chan->srej_list);
4898
4899 l2cap_pass_to_tx(chan, control);
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 err = l2cap_rx_queued_iframes(chan);
4906 if (err)
4907 break;
4908
4909 break;
4910 case L2CAP_TXSEQ_UNEXPECTED:
4911 /* Got a frame that can't be reassembled yet.
4912 * Save it for later, and send SREJs to cover
4913 * the missing frames.
4914 */
4915 skb_queue_tail(&chan->srej_q, skb);
4916 skb_in_use = 1;
4917 BT_DBG("Queued %p (queue len %d)", skb,
4918 skb_queue_len(&chan->srej_q));
4919
4920 l2cap_pass_to_tx(chan, control);
4921 l2cap_send_srej(chan, control->txseq);
4922 break;
4923 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
4924 /* This frame was requested with an SREJ, but
4925 * some expected retransmitted frames are
4926 * missing. Request retransmission of missing
4927 * SREJ'd frames.
4928 */
4929 skb_queue_tail(&chan->srej_q, skb);
4930 skb_in_use = 1;
4931 BT_DBG("Queued %p (queue len %d)", skb,
4932 skb_queue_len(&chan->srej_q));
4933
4934 l2cap_pass_to_tx(chan, control);
4935 l2cap_send_srej_list(chan, control->txseq);
4936 break;
4937 case L2CAP_TXSEQ_DUPLICATE_SREJ:
4938 /* We've already queued this frame. Drop this copy. */
4939 l2cap_pass_to_tx(chan, control);
4940 break;
4941 case L2CAP_TXSEQ_DUPLICATE:
4942 /* Expecting a later sequence number, so this frame
4943 * was already received. Ignore it completely.
4944 */
4945 break;
4946 case L2CAP_TXSEQ_INVALID_IGNORE:
4947 break;
4948 case L2CAP_TXSEQ_INVALID:
4949 default:
4950 l2cap_send_disconn_req(chan->conn, chan,
4951 ECONNRESET);
4952 break;
4953 }
4954 break;
4955 case L2CAP_EV_RECV_RR:
4956 l2cap_pass_to_tx(chan, control);
4957 if (control->final) {
4958 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4959
4960 if (!test_and_clear_bit(CONN_REJ_ACT,
4961 &chan->conn_state)) {
4962 control->final = 0;
4963 l2cap_retransmit_all(chan, control);
4964 }
4965
4966 l2cap_ertm_send(chan);
4967 } else if (control->poll) {
4968 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4969 &chan->conn_state) &&
4970 chan->unacked_frames) {
4971 __set_retrans_timer(chan);
4972 }
4973
4974 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4975 l2cap_send_srej_tail(chan);
4976 } else {
4977 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4978 &chan->conn_state) &&
4979 chan->unacked_frames)
4980 __set_retrans_timer(chan);
4981
4982 l2cap_send_ack(chan);
4983 }
4984 break;
4985 case L2CAP_EV_RECV_RNR:
4986 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4987 l2cap_pass_to_tx(chan, control);
4988 if (control->poll) {
4989 l2cap_send_srej_tail(chan);
4990 } else {
4991 struct l2cap_ctrl rr_control;
4992 memset(&rr_control, 0, sizeof(rr_control));
4993 rr_control.sframe = 1;
4994 rr_control.super = L2CAP_SUPER_RR;
4995 rr_control.reqseq = chan->buffer_seq;
4996 l2cap_send_sframe(chan, &rr_control);
4997 }
4998
4999 break;
5000 case L2CAP_EV_RECV_REJ:
5001 l2cap_handle_rej(chan, control);
5002 break;
5003 case L2CAP_EV_RECV_SREJ:
5004 l2cap_handle_srej(chan, control);
5005 break;
5006 }
5007
5008 if (skb && !skb_in_use) {
5009 BT_DBG("Freeing %p", skb);
5010 kfree_skb(skb);
5011 }
5012
5013 return err;
5014}
5015
5016static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
5017{
5018 /* Make sure reqseq is for a packet that has been sent but not acked */
5019 u16 unacked;
5020
5021 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
5022 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
5023}
5024
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005025static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5026 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005027{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005028 int err = 0;
5029
5030 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
5031 control, skb, event, chan->rx_state);
5032
5033 if (__valid_reqseq(chan, control->reqseq)) {
5034 switch (chan->rx_state) {
5035 case L2CAP_RX_STATE_RECV:
5036 err = l2cap_rx_state_recv(chan, control, skb, event);
5037 break;
5038 case L2CAP_RX_STATE_SREJ_SENT:
5039 err = l2cap_rx_state_srej_sent(chan, control, skb,
5040 event);
5041 break;
5042 default:
5043 /* shut it down */
5044 break;
5045 }
5046 } else {
5047 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
5048 control->reqseq, chan->next_tx_seq,
5049 chan->expected_ack_seq);
5050 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
5051 }
5052
5053 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005054}
5055
5056static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5057 struct sk_buff *skb)
5058{
Mat Martineau4b51dae92012-05-17 20:53:37 -07005059 int err = 0;
5060
5061 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
5062 chan->rx_state);
5063
5064 if (l2cap_classify_txseq(chan, control->txseq) ==
5065 L2CAP_TXSEQ_EXPECTED) {
5066 l2cap_pass_to_tx(chan, control);
5067
5068 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
5069 __next_seq(chan, chan->buffer_seq));
5070
5071 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5072
5073 l2cap_reassemble_sdu(chan, skb, control);
5074 } else {
5075 if (chan->sdu) {
5076 kfree_skb(chan->sdu);
5077 chan->sdu = NULL;
5078 }
5079 chan->sdu_last_frag = NULL;
5080 chan->sdu_len = 0;
5081
5082 if (skb) {
5083 BT_DBG("Freeing %p", skb);
5084 kfree_skb(skb);
5085 }
5086 }
5087
5088 chan->last_acked_seq = control->txseq;
5089 chan->expected_tx_seq = __next_seq(chan, control->txseq);
5090
5091 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005092}
5093
5094static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
5095{
5096 struct l2cap_ctrl *control = &bt_cb(skb)->control;
5097 u16 len;
5098 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005099
Mat Martineaub76bbd62012-04-11 10:48:43 -07005100 __unpack_control(chan, skb);
5101
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005102 len = skb->len;
5103
5104 /*
5105 * We can just drop the corrupted I-frame here.
5106 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005107 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005108 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005109 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005110 goto drop;
5111
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005112 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005113 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005114
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005115 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005116 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005117
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005118 if (len > chan->mps) {
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005119 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005120 goto drop;
5121 }
5122
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005123 if (!control->sframe) {
5124 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005125
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005126 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
5127 control->sar, control->reqseq, control->final,
5128 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03005129
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005130 /* Validate F-bit - F=0 always valid, F=1 only
5131 * valid in TX WAIT_F
5132 */
5133 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005134 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005135
5136 if (chan->mode != L2CAP_MODE_STREAMING) {
5137 event = L2CAP_EV_RECV_IFRAME;
5138 err = l2cap_rx(chan, control, skb, event);
5139 } else {
5140 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005141 }
5142
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005143 if (err)
5144 l2cap_send_disconn_req(chan->conn, chan,
5145 ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005146 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005147 const u8 rx_func_to_event[4] = {
5148 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
5149 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
5150 };
5151
5152 /* Only I-frames are expected in streaming mode */
5153 if (chan->mode == L2CAP_MODE_STREAMING)
5154 goto drop;
5155
5156 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
5157 control->reqseq, control->final, control->poll,
5158 control->super);
5159
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005160 if (len != 0) {
5161 BT_ERR("%d", len);
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005162 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005163 goto drop;
5164 }
5165
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005166 /* Validate F and P bits */
5167 if (control->final && (control->poll ||
5168 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
5169 goto drop;
5170
5171 event = rx_func_to_event[control->super];
5172 if (l2cap_rx(chan, control, skb, event))
5173 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005174 }
5175
5176 return 0;
5177
5178drop:
5179 kfree_skb(skb);
5180 return 0;
5181}
5182
Linus Torvalds1da177e2005-04-16 15:20:36 -07005183static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
5184{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005185 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005186
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03005187 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005188 if (!chan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005189 BT_DBG("unknown cid 0x%4.4x", cid);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005190 /* Drop packet and return */
Dan Carpenter33790132012-02-28 09:52:46 +03005191 kfree_skb(skb);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005192 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005193 }
5194
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03005195 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005196
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005197 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005198 goto drop;
5199
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005200 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005201 case L2CAP_MODE_BASIC:
5202 /* If socket recv buffers overflows we drop data here
5203 * which is *bad* because L2CAP has to be reliable.
5204 * But we don't have any other choice. L2CAP doesn't
5205 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005206
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005207 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005208 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005209
Gustavo F. Padovan23070492011-05-16 17:57:22 -03005210 if (!chan->ops->recv(chan->data, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005211 goto done;
5212 break;
5213
5214 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005215 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005216 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005217 goto done;
5218
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005219 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005220 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005221 break;
5222 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005223
5224drop:
5225 kfree_skb(skb);
5226
5227done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005228 l2cap_chan_unlock(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +02005229
Linus Torvalds1da177e2005-04-16 15:20:36 -07005230 return 0;
5231}
5232
Al Viro8e036fc2007-07-29 00:16:36 -07005233static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005234{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005235 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005236
Ido Yarivc2287682012-04-20 15:46:07 -03005237 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005238 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005239 goto drop;
5240
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005241 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005242
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005243 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005244 goto drop;
5245
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005246 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005247 goto drop;
5248
Gustavo F. Padovan23070492011-05-16 17:57:22 -03005249 if (!chan->ops->recv(chan->data, skb))
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005250 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005251
5252drop:
5253 kfree_skb(skb);
5254
Linus Torvalds1da177e2005-04-16 15:20:36 -07005255 return 0;
5256}
5257
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02005258static inline int l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
5259 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005260{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005261 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005262
Ido Yarivc2287682012-04-20 15:46:07 -03005263 chan = l2cap_global_chan_by_scid(0, cid, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005264 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005265 goto drop;
5266
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005267 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005268
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005269 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005270 goto drop;
5271
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005272 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005273 goto drop;
5274
Gustavo F. Padovan23070492011-05-16 17:57:22 -03005275 if (!chan->ops->recv(chan->data, skb))
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005276 return 0;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005277
5278drop:
5279 kfree_skb(skb);
5280
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005281 return 0;
5282}
5283
Linus Torvalds1da177e2005-04-16 15:20:36 -07005284static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
5285{
5286 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07005287 u16 cid, len;
5288 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005289
5290 skb_pull(skb, L2CAP_HDR_SIZE);
5291 cid = __le16_to_cpu(lh->cid);
5292 len = __le16_to_cpu(lh->len);
5293
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005294 if (len != skb->len) {
5295 kfree_skb(skb);
5296 return;
5297 }
5298
Linus Torvalds1da177e2005-04-16 15:20:36 -07005299 BT_DBG("len %d, cid 0x%4.4x", len, cid);
5300
5301 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005302 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005303 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005304 l2cap_sig_channel(conn, skb);
5305 break;
5306
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005307 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02005308 psm = get_unaligned((__le16 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005309 skb_pull(skb, 2);
5310 l2cap_conless_channel(conn, psm, skb);
5311 break;
5312
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005313 case L2CAP_CID_LE_DATA:
5314 l2cap_att_channel(conn, cid, skb);
5315 break;
5316
Anderson Brigliab501d6a2011-06-07 18:46:31 -03005317 case L2CAP_CID_SMP:
5318 if (smp_sig_channel(conn, skb))
5319 l2cap_conn_del(conn->hcon, EACCES);
5320 break;
5321
Linus Torvalds1da177e2005-04-16 15:20:36 -07005322 default:
5323 l2cap_data_channel(conn, cid, skb);
5324 break;
5325 }
5326}
5327
5328/* ---- L2CAP interface with lower layer (HCI) ---- */
5329
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005330int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005331{
5332 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005333 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005334
Linus Torvalds1da177e2005-04-16 15:20:36 -07005335 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
5336
5337 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005338 read_lock(&chan_list_lock);
5339 list_for_each_entry(c, &chan_list, global_l) {
5340 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005341
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005342 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005343 continue;
5344
5345 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005346 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005347 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005348 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005349 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005350 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
5351 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005352 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005353 lm2 |= HCI_LM_MASTER;
5354 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005355 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005356 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005357
5358 return exact ? lm1 : lm2;
5359}
5360
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005361int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005362{
Marcel Holtmann01394182006-07-03 10:02:46 +02005363 struct l2cap_conn *conn;
5364
Linus Torvalds1da177e2005-04-16 15:20:36 -07005365 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
5366
Linus Torvalds1da177e2005-04-16 15:20:36 -07005367 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005368 conn = l2cap_conn_add(hcon, status);
5369 if (conn)
5370 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02005371 } else
Joe Perchese1750722011-06-29 18:18:29 -07005372 l2cap_conn_del(hcon, bt_to_errno(status));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005373
5374 return 0;
5375}
5376
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005377int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01005378{
5379 struct l2cap_conn *conn = hcon->l2cap_data;
5380
5381 BT_DBG("hcon %p", hcon);
5382
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005383 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02005384 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01005385 return conn->disc_reason;
5386}
5387
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005388int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005389{
5390 BT_DBG("hcon %p reason %d", hcon, reason);
5391
Joe Perchese1750722011-06-29 18:18:29 -07005392 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005393 return 0;
5394}
5395
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005396static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005397{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03005398 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01005399 return;
5400
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005401 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005402 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005403 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005404 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03005405 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005406 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005407 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03005408 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005409 }
5410}
5411
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005412int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005413{
Marcel Holtmann40be4922008-07-14 20:13:50 +02005414 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005415 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005416
Marcel Holtmann01394182006-07-03 10:02:46 +02005417 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005418 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02005419
Linus Torvalds1da177e2005-04-16 15:20:36 -07005420 BT_DBG("conn %p", conn);
5421
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005422 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05305423 if (!status && encrypt)
5424 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02005425 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005426 }
5427
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005428 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005429
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005430 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005431 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005432
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005433 BT_DBG("chan->scid %d", chan->scid);
5434
5435 if (chan->scid == L2CAP_CID_LE_DATA) {
5436 if (!status && encrypt) {
5437 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02005438 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005439 }
5440
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005441 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005442 continue;
5443 }
5444
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03005445 if (test_bit(CONF_CONNECT_PEND, &chan->conf_state)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005446 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01005447 continue;
5448 }
5449
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005450 if (!status && (chan->state == BT_CONNECTED ||
5451 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03005452 struct sock *sk = chan->sk;
5453
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005454 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03005455 sk->sk_state_change(sk);
5456
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005457 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005458 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02005459 continue;
5460 }
5461
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005462 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005463 if (!status) {
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02005464 l2cap_send_conn_req(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005465 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005466 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005467 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005468 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005469 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005470 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005471 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005472
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005473 lock_sock(sk);
5474
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005475 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005476 if (test_bit(BT_SK_DEFER_SETUP,
5477 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005478 struct sock *parent = bt_sk(sk)->parent;
5479 res = L2CAP_CR_PEND;
5480 stat = L2CAP_CS_AUTHOR_PEND;
Ilia Kolomisnky05e9a2f2011-07-15 18:30:21 +00005481 if (parent)
5482 parent->sk_data_ready(parent, 0);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005483 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005484 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005485 res = L2CAP_CR_SUCCESS;
5486 stat = L2CAP_CS_NO_INFO;
5487 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005488 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005489 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005490 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005491 res = L2CAP_CR_SEC_BLOCK;
5492 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005493 }
5494
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005495 release_sock(sk);
5496
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03005497 rsp.scid = cpu_to_le16(chan->dcid);
5498 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005499 rsp.result = cpu_to_le16(res);
5500 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03005501 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
5502 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07005503
5504 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
5505 res == L2CAP_CR_SUCCESS) {
5506 char buf[128];
5507 set_bit(CONF_REQ_SENT, &chan->conf_state);
5508 l2cap_send_cmd(conn, l2cap_get_ident(conn),
5509 L2CAP_CONF_REQ,
5510 l2cap_build_conf_req(chan, buf),
5511 buf);
5512 chan->num_conf_req++;
5513 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005514 }
5515
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005516 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005517 }
5518
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005519 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005520
Linus Torvalds1da177e2005-04-16 15:20:36 -07005521 return 0;
5522}
5523
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005524int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005525{
5526 struct l2cap_conn *conn = hcon->l2cap_data;
5527
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02005528 if (!conn)
5529 conn = l2cap_conn_add(hcon, 0);
5530
5531 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005532 goto drop;
5533
5534 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
5535
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +02005536 if (!(flags & ACL_CONT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005537 struct l2cap_hdr *hdr;
5538 int len;
5539
5540 if (conn->rx_len) {
5541 BT_ERR("Unexpected start frame (len %d)", skb->len);
5542 kfree_skb(conn->rx_skb);
5543 conn->rx_skb = NULL;
5544 conn->rx_len = 0;
5545 l2cap_conn_unreliable(conn, ECOMM);
5546 }
5547
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03005548 /* Start fragment always begin with Basic L2CAP header */
5549 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005550 BT_ERR("Frame is too short (len %d)", skb->len);
5551 l2cap_conn_unreliable(conn, ECOMM);
5552 goto drop;
5553 }
5554
5555 hdr = (struct l2cap_hdr *) skb->data;
5556 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
5557
5558 if (len == skb->len) {
5559 /* Complete frame received */
5560 l2cap_recv_frame(conn, skb);
5561 return 0;
5562 }
5563
5564 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
5565
5566 if (skb->len > len) {
5567 BT_ERR("Frame is too long (len %d, expected len %d)",
5568 skb->len, len);
5569 l2cap_conn_unreliable(conn, ECOMM);
5570 goto drop;
5571 }
5572
5573 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03005574 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
5575 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005576 goto drop;
5577
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005578 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01005579 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005580 conn->rx_len = len - skb->len;
5581 } else {
5582 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
5583
5584 if (!conn->rx_len) {
5585 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
5586 l2cap_conn_unreliable(conn, ECOMM);
5587 goto drop;
5588 }
5589
5590 if (skb->len > conn->rx_len) {
5591 BT_ERR("Fragment is too long (len %d, expected %d)",
5592 skb->len, conn->rx_len);
5593 kfree_skb(conn->rx_skb);
5594 conn->rx_skb = NULL;
5595 conn->rx_len = 0;
5596 l2cap_conn_unreliable(conn, ECOMM);
5597 goto drop;
5598 }
5599
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005600 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01005601 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005602 conn->rx_len -= skb->len;
5603
5604 if (!conn->rx_len) {
5605 /* Complete frame received */
5606 l2cap_recv_frame(conn, conn->rx_skb);
5607 conn->rx_skb = NULL;
5608 }
5609 }
5610
5611drop:
5612 kfree_skb(skb);
5613 return 0;
5614}
5615
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005616static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005617{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005618 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005619
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005620 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005621
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005622 list_for_each_entry(c, &chan_list, global_l) {
5623 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005624
Gustavo F. Padovan903d3432011-02-10 14:16:06 -02005625 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 +01005626 batostr(&bt_sk(sk)->src),
5627 batostr(&bt_sk(sk)->dst),
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005628 c->state, __le16_to_cpu(c->psm),
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005629 c->scid, c->dcid, c->imtu, c->omtu,
5630 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02005631 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005632
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005633 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005634
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005635 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005636}
5637
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005638static int l2cap_debugfs_open(struct inode *inode, struct file *file)
5639{
5640 return single_open(file, l2cap_debugfs_show, inode->i_private);
5641}
5642
5643static const struct file_operations l2cap_debugfs_fops = {
5644 .open = l2cap_debugfs_open,
5645 .read = seq_read,
5646 .llseek = seq_lseek,
5647 .release = single_release,
5648};
5649
5650static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005651
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005652int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005653{
5654 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005655
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005656 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005657 if (err < 0)
5658 return err;
5659
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005660 if (bt_debugfs) {
5661 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
5662 bt_debugfs, NULL, &l2cap_debugfs_fops);
5663 if (!l2cap_debugfs)
5664 BT_ERR("Failed to create L2CAP debug file");
5665 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005666
Linus Torvalds1da177e2005-04-16 15:20:36 -07005667 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005668}
5669
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005670void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005671{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005672 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005673 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005674}
5675
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03005676module_param(disable_ertm, bool, 0644);
5677MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");