blob: 603742fc17a7ca650bd11303c2599394fda979ed [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
Gustavo F. Padovance5706b2010-07-13 11:57:11 -03004 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
Gustavo F. Padovan5d8868f2010-07-16 16:18:39 -03005 Copyright (C) 2010 Google Inc.
Gustavo F. Padovan590051d2011-12-18 13:39:33 -02006 Copyright (C) 2011 ProFUSION Embedded Systems
Mat Martineau422e9252012-04-27 16:50:55 -07007 Copyright (c) 2012 Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07008
9 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License version 2 as
13 published by the Free Software Foundation;
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
18 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090019 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090024 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
25 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070026 SOFTWARE IS DISCLAIMED.
27*/
28
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -020029/* Bluetooth L2CAP core. */
Linus Torvalds1da177e2005-04-16 15:20:36 -070030
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/module.h>
32
Marcel Holtmannaef7d972010-03-21 05:27:45 +010033#include <linux/debugfs.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030034#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36#include <net/bluetooth/bluetooth.h>
37#include <net/bluetooth/hci_core.h>
38#include <net/bluetooth/l2cap.h>
Anderson Brigliab501d6a2011-06-07 18:46:31 -030039#include <net/bluetooth/smp.h>
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +030040#include <net/bluetooth/a2mp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041
Mat Martineaud1de6d42012-05-17 20:53:55 -070042bool disable_ertm;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020043
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070044static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Mat Martineau50a147c2011-11-02 16:18:34 -070045static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070046
Johannes Bergb5ad8b72011-06-01 08:54:45 +020047static LIST_HEAD(chan_list);
48static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
Linus Torvalds1da177e2005-04-16 15:20:36 -070050static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +010051 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030052static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
Gustavo Padovan2d792812012-10-06 10:07:01 +010053 void *data);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -030054static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030055static void l2cap_send_disconn_req(struct l2cap_conn *conn,
Gustavo Padovanc5daa682012-05-16 12:17:10 -030056 struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Gustavo Padovand6603662012-05-21 13:58:22 -030058static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
Gustavo Padovan2d792812012-10-06 10:07:01 +010059 struct sk_buff_head *skbs, u8 event);
Mat Martineau608bcc62012-05-17 20:53:32 -070060
Marcel Holtmann01394182006-07-03 10:02:46 +020061/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030062
Gustavo Padovan2d792812012-10-06 10:07:01 +010063static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
64 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020065{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020066 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030067
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020068 list_for_each_entry(c, &conn->chan_l, list) {
69 if (c->dcid == cid)
70 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020071 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020072 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020073}
74
Gustavo Padovan2d792812012-10-06 10:07:01 +010075static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
76 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020077{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020078 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030079
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020080 list_for_each_entry(c, &conn->chan_l, list) {
81 if (c->scid == cid)
82 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020083 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020084 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020085}
86
87/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -070088 * Returns locked channel. */
Gustavo Padovan2d792812012-10-06 10:07:01 +010089static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
90 u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020091{
Gustavo F. Padovan48454072011-03-25 00:22:30 -030092 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030093
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020094 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030095 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -070096 if (c)
97 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020098 mutex_unlock(&conn->chan_lock);
99
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300100 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200101}
102
Gustavo Padovan2d792812012-10-06 10:07:01 +0100103static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
104 u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200105{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200106 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300107
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200108 list_for_each_entry(c, &conn->chan_l, list) {
109 if (c->ident == ident)
110 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200111 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200112 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200113}
114
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300115static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300116{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300117 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300118
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300119 list_for_each_entry(c, &chan_list, global_l) {
120 if (c->sport == psm && !bacmp(&bt_sk(c->sk)->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100121 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300122 }
Szymon Janc250938c2011-11-16 09:32:22 +0100123 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300124}
125
126int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
127{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300128 int err;
129
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200130 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300131
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300132 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300133 err = -EADDRINUSE;
134 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300135 }
136
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300137 if (psm) {
138 chan->psm = psm;
139 chan->sport = psm;
140 err = 0;
141 } else {
142 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300143
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300144 err = -EINVAL;
145 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300146 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300147 chan->psm = cpu_to_le16(p);
148 chan->sport = cpu_to_le16(p);
149 err = 0;
150 break;
151 }
152 }
153
154done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200155 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300156 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300157}
158
159int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
160{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200161 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300162
163 chan->scid = scid;
164
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200165 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300166
167 return 0;
168}
169
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300170static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200171{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300172 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200173
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300174 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300175 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200176 return cid;
177 }
178
179 return 0;
180}
181
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200182static void __l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300183{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200184 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo Padovan2d792812012-10-06 10:07:01 +0100185 state_to_string(state));
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200186
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300187 chan->state = state;
Gustavo Padovan80b98022012-05-27 22:27:51 -0300188 chan->ops->state_change(chan, state);
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300189}
190
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200191static void l2cap_state_change(struct l2cap_chan *chan, int state)
192{
193 struct sock *sk = chan->sk;
194
195 lock_sock(sk);
196 __l2cap_state_change(chan, state);
197 release_sock(sk);
198}
199
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200200static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err)
201{
202 struct sock *sk = chan->sk;
203
204 sk->sk_err = err;
205}
206
207static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
208{
209 struct sock *sk = chan->sk;
210
211 lock_sock(sk);
212 __l2cap_chan_set_err(chan, err);
213 release_sock(sk);
214}
215
Mat Martineau4239d162012-05-17 20:53:49 -0700216static void __set_retrans_timer(struct l2cap_chan *chan)
217{
218 if (!delayed_work_pending(&chan->monitor_timer) &&
219 chan->retrans_timeout) {
220 l2cap_set_timer(chan, &chan->retrans_timer,
221 msecs_to_jiffies(chan->retrans_timeout));
222 }
223}
224
225static void __set_monitor_timer(struct l2cap_chan *chan)
226{
227 __clear_retrans_timer(chan);
228 if (chan->monitor_timeout) {
229 l2cap_set_timer(chan, &chan->monitor_timer,
230 msecs_to_jiffies(chan->monitor_timeout));
231 }
232}
233
Mat Martineau608bcc62012-05-17 20:53:32 -0700234static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
235 u16 seq)
236{
237 struct sk_buff *skb;
238
239 skb_queue_walk(head, skb) {
240 if (bt_cb(skb)->control.txseq == seq)
241 return skb;
242 }
243
244 return NULL;
245}
246
Mat Martineau3c588192012-04-11 10:48:42 -0700247/* ---- L2CAP sequence number lists ---- */
248
249/* For ERTM, ordered lists of sequence numbers must be tracked for
250 * SREJ requests that are received and for frames that are to be
251 * retransmitted. These seq_list functions implement a singly-linked
252 * list in an array, where membership in the list can also be checked
253 * in constant time. Items can also be added to the tail of the list
254 * and removed from the head in constant time, without further memory
255 * allocs or frees.
256 */
257
258static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
259{
260 size_t alloc_size, i;
261
262 /* Allocated size is a power of 2 to map sequence numbers
263 * (which may be up to 14 bits) in to a smaller array that is
264 * sized for the negotiated ERTM transmit windows.
265 */
266 alloc_size = roundup_pow_of_two(size);
267
268 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
269 if (!seq_list->list)
270 return -ENOMEM;
271
272 seq_list->mask = alloc_size - 1;
273 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
274 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
275 for (i = 0; i < alloc_size; i++)
276 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
277
278 return 0;
279}
280
281static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
282{
283 kfree(seq_list->list);
284}
285
286static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
287 u16 seq)
288{
289 /* Constant-time check for list membership */
290 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
291}
292
293static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
294{
295 u16 mask = seq_list->mask;
296
297 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
298 /* In case someone tries to pop the head of an empty list */
299 return L2CAP_SEQ_LIST_CLEAR;
300 } else if (seq_list->head == seq) {
301 /* Head can be removed in constant time */
302 seq_list->head = seq_list->list[seq & mask];
303 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
304
305 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
306 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
307 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
308 }
309 } else {
310 /* Walk the list to find the sequence number */
311 u16 prev = seq_list->head;
312 while (seq_list->list[prev & mask] != seq) {
313 prev = seq_list->list[prev & mask];
314 if (prev == L2CAP_SEQ_LIST_TAIL)
315 return L2CAP_SEQ_LIST_CLEAR;
316 }
317
318 /* Unlink the number from the list and clear it */
319 seq_list->list[prev & mask] = seq_list->list[seq & mask];
320 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
321 if (seq_list->tail == seq)
322 seq_list->tail = prev;
323 }
324 return seq;
325}
326
327static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
328{
329 /* Remove the head in constant time */
330 return l2cap_seq_list_remove(seq_list, seq_list->head);
331}
332
333static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
334{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300335 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700336
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300337 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
338 return;
339
340 for (i = 0; i <= seq_list->mask; i++)
341 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
342
343 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
344 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700345}
346
347static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
348{
349 u16 mask = seq_list->mask;
350
351 /* All appends happen in constant time */
352
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300353 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
354 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700355
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300356 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
357 seq_list->head = seq;
358 else
359 seq_list->list[seq_list->tail & mask] = seq;
360
361 seq_list->tail = seq;
362 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700363}
364
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300365static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300366{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300367 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100368 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200369 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300370 int reason;
371
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200372 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300373
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200374 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200375 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300376
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300377 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300378 reason = ECONNREFUSED;
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300379 else if (chan->state == BT_CONNECT &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100380 chan->sec_level != BT_SECURITY_SDP)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300381 reason = ECONNREFUSED;
382 else
383 reason = ETIMEDOUT;
384
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300385 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300386
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200387 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300388
Gustavo Padovan80b98022012-05-27 22:27:51 -0300389 chan->ops->close(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200390 mutex_unlock(&conn->chan_lock);
391
Ulisses Furquim371fd832011-12-21 20:02:36 -0200392 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300393}
394
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300395struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200396{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300397 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200398
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300399 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
400 if (!chan)
401 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200402
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200403 mutex_init(&chan->lock);
404
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200405 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300406 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200407 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300408
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300409 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300410
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300411 chan->state = BT_OPEN;
412
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530413 kref_init(&chan->kref);
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300414
Mat Martineau28270112012-05-17 21:14:09 -0700415 /* This flag is cleared in l2cap_chan_ready() */
416 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
417
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300418 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100419
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300420 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200421}
422
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530423static void l2cap_chan_destroy(struct kref *kref)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300424{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530425 struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
426
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530427 BT_DBG("chan %p", chan);
428
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200429 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300430 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200431 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300432
Jaganath Kanakkassery4af66c62012-07-13 18:17:55 +0530433 kfree(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300434}
435
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530436void l2cap_chan_hold(struct l2cap_chan *c)
437{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530438 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530439
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530440 kref_get(&c->kref);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530441}
442
443void l2cap_chan_put(struct l2cap_chan *c)
444{
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530445 BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->kref.refcount));
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530446
Syam Sidhardhan144ad332012-07-27 23:51:21 +0530447 kref_put(&c->kref, l2cap_chan_destroy);
Jaganath Kanakkassery30648372012-07-13 18:17:54 +0530448}
449
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300450void l2cap_chan_set_defaults(struct l2cap_chan *chan)
451{
452 chan->fcs = L2CAP_FCS_CRC16;
453 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
454 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
455 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
Mat Martineauc20f8e32012-07-10 05:47:07 -0700456 chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300457 chan->sec_level = BT_SECURITY_LOW;
458
459 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
460}
461
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300462void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200463{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300464 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200465 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200466
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200467 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100468
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300469 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200470
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200471 switch (chan->chan_type) {
472 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300473 if (conn->hcon->type == LE_LINK) {
474 /* LE connection */
Andre Guedes6fcb06a2012-05-31 17:01:33 -0300475 chan->omtu = L2CAP_DEFAULT_MTU;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300476 chan->scid = L2CAP_CID_LE_DATA;
477 chan->dcid = L2CAP_CID_LE_DATA;
Ville Tervob62f3282011-02-10 22:38:50 -0300478 } else {
479 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300480 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300481 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300482 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200483 break;
484
485 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200486 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300487 chan->scid = L2CAP_CID_CONN_LESS;
488 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300489 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200490 break;
491
Andrei Emeltchenko416fa752012-05-29 13:59:16 +0300492 case L2CAP_CHAN_CONN_FIX_A2MP:
493 chan->scid = L2CAP_CID_A2MP;
494 chan->dcid = L2CAP_CID_A2MP;
495 chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
496 chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
497 break;
498
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200499 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200500 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300501 chan->scid = L2CAP_CID_SIGNALING;
502 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300503 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200504 }
505
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300506 chan->local_id = L2CAP_BESTEFFORT_ID;
507 chan->local_stype = L2CAP_SERV_BESTEFFORT;
508 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
509 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
510 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +0300511 chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO;
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300512
Ulisses Furquim371fd832011-12-21 20:02:36 -0200513 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300514
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200515 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200516}
517
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300518void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200519{
520 mutex_lock(&conn->chan_lock);
521 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200522 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200523}
524
Andrei Emeltchenko466f8002012-05-29 13:59:01 +0300525void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200526{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300527 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200528
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300529 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200530
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300531 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200532
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900533 if (conn) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300534 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200535 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200536
Ulisses Furquim371fd832011-12-21 20:02:36 -0200537 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300538
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300539 chan->conn = NULL;
Andrei Emeltchenko3cabbfd2012-05-31 11:01:37 +0300540
541 if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP)
542 hci_conn_put(conn->hcon);
Marcel Holtmann01394182006-07-03 10:02:46 +0200543 }
544
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100545 chan->ops->teardown(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200546
Mat Martineau28270112012-05-17 21:14:09 -0700547 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300548 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300549
Gustavo Padovanee556f62012-05-18 20:22:38 -0300550 switch(chan->mode) {
551 case L2CAP_MODE_BASIC:
552 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300553
Gustavo Padovanee556f62012-05-18 20:22:38 -0300554 case L2CAP_MODE_ERTM:
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -0300555 __clear_retrans_timer(chan);
556 __clear_monitor_timer(chan);
557 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300558
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -0300559 skb_queue_purge(&chan->srej_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300560
Mat Martineau3c588192012-04-11 10:48:42 -0700561 l2cap_seq_list_free(&chan->srej_list);
562 l2cap_seq_list_free(&chan->retrans_list);
Gustavo Padovanee556f62012-05-18 20:22:38 -0300563
564 /* fall through */
565
566 case L2CAP_MODE_STREAMING:
567 skb_queue_purge(&chan->tx_q);
568 break;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300569 }
Gustavo Padovanee556f62012-05-18 20:22:38 -0300570
571 return;
Marcel Holtmann01394182006-07-03 10:02:46 +0200572}
573
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300574void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300575{
576 struct l2cap_conn *conn = chan->conn;
577 struct sock *sk = chan->sk;
578
Gustavo Padovan2d792812012-10-06 10:07:01 +0100579 BT_DBG("chan %p state %s sk %p", chan, state_to_string(chan->state),
580 sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300581
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300582 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300583 case BT_LISTEN:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100584 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300585 break;
586
587 case BT_CONNECTED:
588 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300589 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100590 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300591 __set_chan_timer(chan, sk->sk_sndtimeo);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300592 l2cap_send_disconn_req(conn, chan, reason);
593 } else
594 l2cap_chan_del(chan, reason);
595 break;
596
597 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300598 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100599 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300600 struct l2cap_conn_rsp rsp;
601 __u16 result;
602
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300603 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300604 result = L2CAP_CR_SEC_BLOCK;
605 else
606 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -0300607 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300608
609 rsp.scid = cpu_to_le16(chan->dcid);
610 rsp.dcid = cpu_to_le16(chan->scid);
611 rsp.result = cpu_to_le16(result);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +0300612 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300613 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100614 sizeof(rsp), &rsp);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300615 }
616
617 l2cap_chan_del(chan, reason);
618 break;
619
620 case BT_CONNECT:
621 case BT_DISCONN:
622 l2cap_chan_del(chan, reason);
623 break;
624
625 default:
Gustavo Padovanb699ec02012-10-06 11:51:54 +0100626 chan->ops->teardown(chan, 0);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300627 break;
628 }
629}
630
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300631static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530632{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300633 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300634 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530635 case BT_SECURITY_HIGH:
636 return HCI_AT_DEDICATED_BONDING_MITM;
637 case BT_SECURITY_MEDIUM:
638 return HCI_AT_DEDICATED_BONDING;
639 default:
640 return HCI_AT_NO_BONDING;
641 }
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +0300642 } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300643 if (chan->sec_level == BT_SECURITY_LOW)
644 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530645
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300646 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530647 return HCI_AT_NO_BONDING_MITM;
648 else
649 return HCI_AT_NO_BONDING;
650 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300651 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530652 case BT_SECURITY_HIGH:
653 return HCI_AT_GENERAL_BONDING_MITM;
654 case BT_SECURITY_MEDIUM:
655 return HCI_AT_GENERAL_BONDING;
656 default:
657 return HCI_AT_NO_BONDING;
658 }
659 }
660}
661
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200662/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200663int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200664{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300665 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100666 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200667
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300668 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100669
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300670 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200671}
672
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200673static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200674{
675 u8 id;
676
677 /* Get next available identificator.
678 * 1 - 128 are used by kernel.
679 * 129 - 199 are reserved.
680 * 200 - 254 are used by utilities like l2ping, etc.
681 */
682
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200683 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200684
685 if (++conn->tx_ident > 128)
686 conn->tx_ident = 1;
687
688 id = conn->tx_ident;
689
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200690 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200691
692 return id;
693}
694
Gustavo Padovan2d792812012-10-06 10:07:01 +0100695static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
696 void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200697{
698 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200699 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200700
701 BT_DBG("code 0x%2.2x", code);
702
703 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300704 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200705
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200706 if (lmp_no_flush_capable(conn->hcon->hdev))
707 flags = ACL_START_NO_FLUSH;
708 else
709 flags = ACL_START;
710
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700711 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200712 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700713
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200714 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200715}
716
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200717static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
718{
719 struct hci_conn *hcon = chan->conn->hcon;
720 u16 flags;
721
722 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
Gustavo Padovan2d792812012-10-06 10:07:01 +0100723 skb->priority);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200724
725 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +0100726 lmp_no_flush_capable(hcon->hdev))
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200727 flags = ACL_START_NO_FLUSH;
728 else
729 flags = ACL_START;
730
731 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
732 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733}
734
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700735static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
736{
737 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
738 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
739
740 if (enh & L2CAP_CTRL_FRAME_TYPE) {
741 /* S-Frame */
742 control->sframe = 1;
743 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
744 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
745
746 control->sar = 0;
747 control->txseq = 0;
748 } else {
749 /* I-Frame */
750 control->sframe = 0;
751 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
752 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
753
754 control->poll = 0;
755 control->super = 0;
756 }
757}
758
759static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
760{
761 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
762 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
763
764 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
765 /* S-Frame */
766 control->sframe = 1;
767 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
768 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
769
770 control->sar = 0;
771 control->txseq = 0;
772 } else {
773 /* I-Frame */
774 control->sframe = 0;
775 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
776 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
777
778 control->poll = 0;
779 control->super = 0;
780 }
781}
782
783static inline void __unpack_control(struct l2cap_chan *chan,
784 struct sk_buff *skb)
785{
786 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
787 __unpack_extended_control(get_unaligned_le32(skb->data),
788 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700789 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700790 } else {
791 __unpack_enhanced_control(get_unaligned_le16(skb->data),
792 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700793 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700794 }
795}
796
797static u32 __pack_extended_control(struct l2cap_ctrl *control)
798{
799 u32 packed;
800
801 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
802 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
803
804 if (control->sframe) {
805 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
806 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
807 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
808 } else {
809 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
810 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
811 }
812
813 return packed;
814}
815
816static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
817{
818 u16 packed;
819
820 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
821 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
822
823 if (control->sframe) {
824 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
825 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
826 packed |= L2CAP_CTRL_FRAME_TYPE;
827 } else {
828 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
829 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
830 }
831
832 return packed;
833}
834
835static inline void __pack_control(struct l2cap_chan *chan,
836 struct l2cap_ctrl *control,
837 struct sk_buff *skb)
838{
839 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
840 put_unaligned_le32(__pack_extended_control(control),
841 skb->data + L2CAP_HDR_SIZE);
842 } else {
843 put_unaligned_le16(__pack_enhanced_control(control),
844 skb->data + L2CAP_HDR_SIZE);
845 }
846}
847
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300848static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
849{
850 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
851 return L2CAP_EXT_HDR_SIZE;
852 else
853 return L2CAP_ENH_HDR_SIZE;
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;
Gustavo Padovanba7aa642012-05-29 13:29:16 -0300861 int hlen = __ertm_hdr_size(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300862
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300863 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300864 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300865
Mat Martineaua67d7f62012-05-17 20:53:35 -0700866 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300867
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300868 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700869 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300870
871 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300872 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300873 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300874
Mat Martineaua67d7f62012-05-17 20:53:35 -0700875 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
876 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
877 else
878 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300879
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300880 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700881 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300882 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300883 }
884
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200885 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700886 return skb;
887}
888
889static void l2cap_send_sframe(struct l2cap_chan *chan,
890 struct l2cap_ctrl *control)
891{
892 struct sk_buff *skb;
893 u32 control_field;
894
895 BT_DBG("chan %p, control %p", chan, control);
896
897 if (!control->sframe)
898 return;
899
900 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
901 !control->poll)
902 control->final = 1;
903
904 if (control->super == L2CAP_SUPER_RR)
905 clear_bit(CONN_RNR_SENT, &chan->conn_state);
906 else if (control->super == L2CAP_SUPER_RNR)
907 set_bit(CONN_RNR_SENT, &chan->conn_state);
908
909 if (control->super != L2CAP_SUPER_SREJ) {
910 chan->last_acked_seq = control->reqseq;
911 __clear_ack_timer(chan);
912 }
913
914 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
915 control->final, control->poll, control->super);
916
917 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
918 control_field = __pack_extended_control(control);
919 else
920 control_field = __pack_enhanced_control(control);
921
922 skb = l2cap_create_sframe_pdu(chan, control_field);
923 if (!IS_ERR(skb))
924 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300925}
926
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700927static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300928{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700929 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300930
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700931 BT_DBG("chan %p, poll %d", chan, poll);
932
933 memset(&control, 0, sizeof(control));
934 control.sframe = 1;
935 control.poll = poll;
936
937 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
938 control.super = L2CAP_SUPER_RNR;
939 else
940 control.super = L2CAP_SUPER_RR;
941
942 control.reqseq = chan->buffer_seq;
943 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300944}
945
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300946static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300947{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -0300948 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300949}
950
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300951static bool __amp_capable(struct l2cap_chan *chan)
952{
953 struct l2cap_conn *conn = chan->conn;
954
955 if (enable_hs &&
956 chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED &&
957 conn->fixed_chan_mask & L2CAP_FC_A2MP)
958 return true;
959 else
960 return false;
961}
962
Andrei Emeltchenko2766be42012-09-27 17:26:21 +0300963void l2cap_send_conn_req(struct l2cap_chan *chan)
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +0200964{
965 struct l2cap_conn *conn = chan->conn;
966 struct l2cap_conn_req req;
967
968 req.scid = cpu_to_le16(chan->scid);
969 req.psm = chan->psm;
970
971 chan->ident = l2cap_get_ident(conn);
972
973 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
974
975 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
976}
977
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300978static void l2cap_chan_ready(struct l2cap_chan *chan)
979{
Mat Martineau28270112012-05-17 21:14:09 -0700980 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300981 chan->conf_state = 0;
982 __clear_chan_timer(chan);
983
Andrei Emeltchenko54a59aa2012-05-27 22:27:53 -0300984 chan->state = BT_CONNECTED;
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300985
Andrei Emeltchenkofd83e2c2012-05-30 09:55:32 +0300986 chan->ops->ready(chan);
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300987}
988
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +0300989static void l2cap_start_connection(struct l2cap_chan *chan)
990{
991 if (__amp_capable(chan)) {
992 BT_DBG("chan %p AMP capable: discover AMPs", chan);
993 a2mp_discover_amp(chan);
994 } else {
995 l2cap_send_conn_req(chan);
996 }
997}
998
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -0300999static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001000{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001001 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001002
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001003 if (conn->hcon->type == LE_LINK) {
1004 l2cap_chan_ready(chan);
1005 return;
1006 }
1007
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001008 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001009 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1010 return;
1011
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001012 if (l2cap_chan_check_security(chan) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001013 __l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001014 l2cap_start_connection(chan);
1015 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001016 } else {
1017 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001018 req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001019
1020 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1021 conn->info_ident = l2cap_get_ident(conn);
1022
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001023 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001024
Gustavo Padovan2d792812012-10-06 10:07:01 +01001025 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
1026 sizeof(req), &req);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001027 }
1028}
1029
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001030static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1031{
1032 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001033 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001034 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1035
1036 switch (mode) {
1037 case L2CAP_MODE_ERTM:
1038 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1039 case L2CAP_MODE_STREAMING:
1040 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1041 default:
1042 return 0x00;
1043 }
1044}
1045
Gustavo Padovan2d792812012-10-06 10:07:01 +01001046static void l2cap_send_disconn_req(struct l2cap_conn *conn,
1047 struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001048{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001049 struct sock *sk = chan->sk;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001050 struct l2cap_disconn_req req;
1051
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001052 if (!conn)
1053 return;
1054
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001055 if (chan->mode == L2CAP_MODE_ERTM) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001056 __clear_retrans_timer(chan);
1057 __clear_monitor_timer(chan);
1058 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001059 }
1060
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001061 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
Gustavo Padovand1177732012-10-06 11:47:38 +01001062 l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001063 return;
1064 }
1065
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001066 req.dcid = cpu_to_le16(chan->dcid);
1067 req.scid = cpu_to_le16(chan->scid);
Gustavo Padovan2d792812012-10-06 10:07:01 +01001068 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
1069 sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001070
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001071 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001072 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001073 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001074 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001075}
1076
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001078static void l2cap_conn_start(struct l2cap_conn *conn)
1079{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001080 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001081
1082 BT_DBG("conn %p", conn);
1083
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001084 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001085
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001086 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001087 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001088
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001089 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001090
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001091 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001092 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001093 continue;
1094 }
1095
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001096 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001097 if (!l2cap_chan_check_security(chan) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001098 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001099 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001100 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001101 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001102
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001103 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
Gustavo Padovan2d792812012-10-06 10:07:01 +01001104 && test_bit(CONF_STATE2_DEVICE,
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001105 &chan->conf_state)) {
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001106 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001107 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001108 continue;
1109 }
1110
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03001111 l2cap_start_connection(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001112
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001113 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001114 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001115 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001116 rsp.scid = cpu_to_le16(chan->dcid);
1117 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001118
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001119 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001120 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001121 if (test_bit(BT_SK_DEFER_SETUP,
1122 &bt_sk(sk)->flags)) {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001123 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1124 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08001125 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001126
1127 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001128 __l2cap_state_change(chan, BT_CONFIG);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001129 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
1130 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001131 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001132 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001133 } else {
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03001134 rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
1135 rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001136 }
1137
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001138 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001139 sizeof(rsp), &rsp);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001140
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001141 if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001142 rsp.result != L2CAP_CR_SUCCESS) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001143 l2cap_chan_unlock(chan);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001144 continue;
1145 }
1146
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001147 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001148 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001149 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03001150 chan->num_conf_req++;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001151 }
1152
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001153 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001154 }
1155
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001156 mutex_unlock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001157}
1158
Ido Yarivc2287682012-04-20 15:46:07 -03001159/* Find socket with cid and source/destination bdaddr.
Ville Tervob62f3282011-02-10 22:38:50 -03001160 * Returns closest match, locked.
1161 */
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02001162static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
Ido Yarivc2287682012-04-20 15:46:07 -03001163 bdaddr_t *src,
1164 bdaddr_t *dst)
Ville Tervob62f3282011-02-10 22:38:50 -03001165{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001166 struct l2cap_chan *c, *c1 = NULL;
Ville Tervob62f3282011-02-10 22:38:50 -03001167
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001168 read_lock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001169
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001170 list_for_each_entry(c, &chan_list, global_l) {
1171 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001172
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001173 if (state && c->state != state)
Ville Tervob62f3282011-02-10 22:38:50 -03001174 continue;
1175
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001176 if (c->scid == cid) {
Ido Yarivc2287682012-04-20 15:46:07 -03001177 int src_match, dst_match;
1178 int src_any, dst_any;
1179
Ville Tervob62f3282011-02-10 22:38:50 -03001180 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001181 src_match = !bacmp(&bt_sk(sk)->src, src);
1182 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1183 if (src_match && dst_match) {
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001184 read_unlock(&chan_list_lock);
1185 return c;
1186 }
Ville Tervob62f3282011-02-10 22:38:50 -03001187
1188 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001189 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1190 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1191 if ((src_match && dst_any) || (src_any && dst_match) ||
1192 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001193 c1 = c;
Ville Tervob62f3282011-02-10 22:38:50 -03001194 }
1195 }
Gustavo F. Padovan280f2942011-04-13 19:01:22 -03001196
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001197 read_unlock(&chan_list_lock);
Ville Tervob62f3282011-02-10 22:38:50 -03001198
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001199 return c1;
Ville Tervob62f3282011-02-10 22:38:50 -03001200}
1201
1202static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1203{
Gustavo F. Padovanc916fbe2011-04-04 16:00:55 -03001204 struct sock *parent, *sk;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001205 struct l2cap_chan *chan, *pchan;
Ville Tervob62f3282011-02-10 22:38:50 -03001206
1207 BT_DBG("");
1208
1209 /* Check if we have socket listening on cid */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001210 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
Ido Yarivc2287682012-04-20 15:46:07 -03001211 conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001212 if (!pchan)
Ville Tervob62f3282011-02-10 22:38:50 -03001213 return;
1214
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001215 parent = pchan->sk;
1216
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001217 lock_sock(parent);
Gustavo F. Padovan62f3a2c2011-04-14 18:34:34 -03001218
Gustavo Padovan80b98022012-05-27 22:27:51 -03001219 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001220 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001221 goto clean;
1222
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001223 sk = chan->sk;
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001224
Ville Tervob62f3282011-02-10 22:38:50 -03001225 hci_conn_hold(conn->hcon);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001226 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
Ville Tervob62f3282011-02-10 22:38:50 -03001227
Ville Tervob62f3282011-02-10 22:38:50 -03001228 bacpy(&bt_sk(sk)->src, conn->src);
1229 bacpy(&bt_sk(sk)->dst, conn->dst);
1230
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001231 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001232
Gustavo Padovan6754e0d2012-05-25 09:30:56 -03001233 l2cap_chan_ready(chan);
Ville Tervob62f3282011-02-10 22:38:50 -03001234
Ville Tervob62f3282011-02-10 22:38:50 -03001235clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001236 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001237}
1238
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001239static void l2cap_conn_ready(struct l2cap_conn *conn)
1240{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001241 struct l2cap_chan *chan;
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001242 struct hci_conn *hcon = conn->hcon;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001243
1244 BT_DBG("conn %p", conn);
1245
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001246 if (!hcon->out && hcon->type == LE_LINK)
Ville Tervob62f3282011-02-10 22:38:50 -03001247 l2cap_le_conn_ready(conn);
1248
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001249 if (hcon->out && hcon->type == LE_LINK)
1250 smp_conn_security(hcon, hcon->pending_sec_level);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001251
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
Andrei Emeltchenko416fa752012-05-29 13:59:16 +03001258 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
1259 l2cap_chan_unlock(chan);
1260 continue;
1261 }
1262
Vinicius Costa Gomescc110922012-08-23 21:32:43 -03001263 if (hcon->type == LE_LINK) {
1264 if (smp_conn_security(hcon, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001265 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001266
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001267 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001268 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001269 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001270 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001271 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001272 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001273 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001274
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001275 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001276 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001277
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001278 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001279 }
1280
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001281 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001282}
1283
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001284/* Notify sockets that we cannot guaranty reliability anymore */
1285static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1286{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001287 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001288
1289 BT_DBG("conn %p", conn);
1290
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001291 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001292
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001293 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001294 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Gustavo Padovan1d8b1fd2012-10-06 11:34:52 +01001295 l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001296 }
1297
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001298 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001299}
1300
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001301static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001302{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001303 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001304 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001305
Marcel Holtmann984947d2009-02-06 23:35:19 +01001306 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001307 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001308
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001309 l2cap_conn_start(conn);
1310}
1311
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001312static void l2cap_conn_del(struct hci_conn *hcon, int err)
1313{
1314 struct l2cap_conn *conn = hcon->l2cap_data;
1315 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001316
1317 if (!conn)
1318 return;
1319
1320 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1321
1322 kfree_skb(conn->rx_skb);
1323
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001324 mutex_lock(&conn->chan_lock);
1325
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001326 /* Kill channels */
1327 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001328 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001329 l2cap_chan_lock(chan);
1330
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001331 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001332
1333 l2cap_chan_unlock(chan);
1334
Gustavo Padovan80b98022012-05-27 22:27:51 -03001335 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001336 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001337 }
1338
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001339 mutex_unlock(&conn->chan_lock);
1340
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001341 hci_chan_del(conn->hchan);
1342
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001343 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001344 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001345
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001346 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001347 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001348 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001349 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001350
1351 hcon->l2cap_data = NULL;
1352 kfree(conn);
1353}
1354
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001355static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001356{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001357 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01001358 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001359
Johan Hedbergd06cc412012-06-06 18:44:11 +08001360 BT_DBG("conn %p", conn);
1361
1362 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
1363 smp_chan_destroy(conn);
1364 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1365 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001366}
1367
Linus Torvalds1da177e2005-04-16 15:20:36 -07001368static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
1369{
Marcel Holtmann01394182006-07-03 10:02:46 +02001370 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001371 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372
Marcel Holtmann01394182006-07-03 10:02:46 +02001373 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374 return conn;
1375
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001376 hchan = hci_chan_create(hcon);
1377 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001380 conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001381 if (!conn) {
1382 hci_chan_del(hchan);
1383 return NULL;
1384 }
1385
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386 hcon->l2cap_data = conn;
1387 conn->hcon = hcon;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001388 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001390 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001391
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001392 switch (hcon->type) {
1393 case AMP_LINK:
1394 conn->mtu = hcon->hdev->block_mtu;
1395 break;
1396
1397 case LE_LINK:
1398 if (hcon->hdev->le_mtu) {
1399 conn->mtu = hcon->hdev->le_mtu;
1400 break;
1401 }
1402 /* fall through */
1403
1404 default:
Ville Tervoacd7d372011-02-10 22:38:49 -03001405 conn->mtu = hcon->hdev->acl_mtu;
Andrei Emeltchenkodcc042d2012-10-05 16:56:57 +03001406 break;
1407 }
Ville Tervoacd7d372011-02-10 22:38:49 -03001408
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 conn->src = &hcon->hdev->bdaddr;
1410 conn->dst = &hcon->dst;
1411
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001412 conn->feat_mask = 0;
1413
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001415 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001416
1417 INIT_LIST_HEAD(&conn->chan_l);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001419 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001420 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001421 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001422 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001423
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001424 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001425
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426 return conn;
1427}
1428
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001430
Ido Yarivc2287682012-04-20 15:46:07 -03001431/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432 * Returns closest match.
1433 */
Ido Yarivc2287682012-04-20 15:46:07 -03001434static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1435 bdaddr_t *src,
1436 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001438 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001439
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001440 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001441
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001442 list_for_each_entry(c, &chan_list, global_l) {
1443 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001444
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001445 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446 continue;
1447
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001448 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001449 int src_match, dst_match;
1450 int src_any, dst_any;
1451
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001453 src_match = !bacmp(&bt_sk(sk)->src, src);
1454 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1455 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001456 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001457 return c;
1458 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459
1460 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001461 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1462 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1463 if ((src_match && dst_any) || (src_any && dst_match) ||
1464 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001465 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466 }
1467 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001469 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001470
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001471 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472}
1473
Andre Guedes8e9f9892012-04-24 21:02:55 -03001474int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1475 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001476{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001477 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001478 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479 struct l2cap_conn *conn;
1480 struct hci_conn *hcon;
1481 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001482 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001483 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001485 BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", src, dst,
Syam Sidhardhanab195162012-07-27 23:51:22 +05301486 dst_type, __le16_to_cpu(psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001488 hdev = hci_get_route(dst, src);
1489 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001490 return -EHOSTUNREACH;
1491
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001492 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001494 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001495
1496 /* PSM must be odd and lsb of upper byte must be 0 */
1497 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01001498 chan->chan_type != L2CAP_CHAN_RAW) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001499 err = -EINVAL;
1500 goto done;
1501 }
1502
1503 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1504 err = -EINVAL;
1505 goto done;
1506 }
1507
1508 switch (chan->mode) {
1509 case L2CAP_MODE_BASIC:
1510 break;
1511 case L2CAP_MODE_ERTM:
1512 case L2CAP_MODE_STREAMING:
1513 if (!disable_ertm)
1514 break;
1515 /* fall through */
1516 default:
1517 err = -ENOTSUPP;
1518 goto done;
1519 }
1520
Gustavo Padovan0797e012012-05-27 22:27:54 -03001521 switch (chan->state) {
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001522 case BT_CONNECT:
1523 case BT_CONNECT2:
1524 case BT_CONFIG:
1525 /* Already connecting */
1526 err = 0;
1527 goto done;
1528
1529 case BT_CONNECTED:
1530 /* Already connected */
1531 err = -EISCONN;
1532 goto done;
1533
1534 case BT_OPEN:
1535 case BT_BOUND:
1536 /* Can connect */
1537 break;
1538
1539 default:
1540 err = -EBADFD;
1541 goto done;
1542 }
1543
1544 /* Set destination address and psm */
Gustavo Padovan0797e012012-05-27 22:27:54 -03001545 lock_sock(sk);
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001546 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001547 release_sock(sk);
1548
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001549 chan->psm = psm;
1550 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001552 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001553
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001554 if (chan->dcid == L2CAP_CID_LE_DATA)
Andre Guedes8e9f9892012-04-24 21:02:55 -03001555 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001556 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001557 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001558 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001559 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001560
Ville Tervo30e76272011-02-22 16:10:53 -03001561 if (IS_ERR(hcon)) {
1562 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001564 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565
1566 conn = l2cap_conn_add(hcon, 0);
1567 if (!conn) {
1568 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001569 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001570 goto done;
1571 }
1572
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001573 if (hcon->type == LE_LINK) {
1574 err = 0;
1575
1576 if (!list_empty(&conn->chan_l)) {
1577 err = -EBUSY;
1578 hci_conn_put(hcon);
1579 }
1580
1581 if (err)
1582 goto done;
1583 }
1584
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585 /* Update source addr of the socket */
1586 bacpy(src, conn->src);
1587
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001588 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001589 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001590 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001591
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001592 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001593 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594
1595 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001596 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001597 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001598 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001599 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001600 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001601 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602 }
1603
Ville Tervo30e76272011-02-22 16:10:53 -03001604 err = 0;
1605
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001607 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001608 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609 hci_dev_put(hdev);
1610 return err;
1611}
1612
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001613int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001614{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001615 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001616 DECLARE_WAITQUEUE(wait, current);
1617 int err = 0;
1618 int timeo = HZ/5;
1619
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001620 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001621 set_current_state(TASK_INTERRUPTIBLE);
1622 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001623 if (!timeo)
1624 timeo = HZ/5;
1625
1626 if (signal_pending(current)) {
1627 err = sock_intr_errno(timeo);
1628 break;
1629 }
1630
1631 release_sock(sk);
1632 timeo = schedule_timeout(timeo);
1633 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001634 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001635
1636 err = sock_error(sk);
1637 if (err)
1638 break;
1639 }
1640 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001641 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001642 return err;
1643}
1644
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001645static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001646{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001647 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001648 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001649
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001650 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001651
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001652 l2cap_chan_lock(chan);
1653
Mat Martineau80909e02012-05-17 20:53:50 -07001654 if (!chan->conn) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001655 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001656 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001657 return;
1658 }
1659
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001660 l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001661
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001662 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001663 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001664}
1665
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001666static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001667{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001668 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001669 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001670
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001671 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001672
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001673 l2cap_chan_lock(chan);
1674
Mat Martineau80909e02012-05-17 20:53:50 -07001675 if (!chan->conn) {
1676 l2cap_chan_unlock(chan);
1677 l2cap_chan_put(chan);
1678 return;
1679 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001680
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03001681 l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001682 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001683 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001684}
1685
Gustavo Padovand6603662012-05-21 13:58:22 -03001686static void l2cap_streaming_send(struct l2cap_chan *chan,
1687 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001688{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001689 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001690 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001691
Mat Martineau37339372012-05-17 20:53:33 -07001692 BT_DBG("chan %p, skbs %p", chan, skbs);
1693
Mat Martineau37339372012-05-17 20:53:33 -07001694 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1695
1696 while (!skb_queue_empty(&chan->tx_q)) {
1697
1698 skb = skb_dequeue(&chan->tx_q);
1699
1700 bt_cb(skb)->control.retries = 1;
1701 control = &bt_cb(skb)->control;
1702
1703 control->reqseq = 0;
1704 control->txseq = chan->next_tx_seq;
1705
1706 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001707
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001708 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001709 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1710 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001711 }
1712
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001713 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001714
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001715 BT_DBG("Sent txseq %u", control->txseq);
Mat Martineau37339372012-05-17 20:53:33 -07001716
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001717 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001718 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001719 }
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001720}
1721
Szymon Janc67c9e842011-07-28 16:24:33 +02001722static int l2cap_ertm_send(struct l2cap_chan *chan)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001723{
1724 struct sk_buff *skb, *tx_skb;
Mat Martineau18a48e72012-05-17 20:53:34 -07001725 struct l2cap_ctrl *control;
1726 int sent = 0;
1727
1728 BT_DBG("chan %p", chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001729
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03001730 if (chan->state != BT_CONNECTED)
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001731 return -ENOTCONN;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001732
Mat Martineau94122bb2012-05-02 09:42:02 -07001733 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1734 return 0;
1735
Mat Martineau18a48e72012-05-17 20:53:34 -07001736 while (chan->tx_send_head &&
1737 chan->unacked_frames < chan->remote_tx_win &&
1738 chan->tx_state == L2CAP_TX_STATE_XMIT) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001739
Mat Martineau18a48e72012-05-17 20:53:34 -07001740 skb = chan->tx_send_head;
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001741
Mat Martineau18a48e72012-05-17 20:53:34 -07001742 bt_cb(skb)->control.retries = 1;
1743 control = &bt_cb(skb)->control;
Gustavo F. Padovan95ffa972010-06-18 20:37:33 -03001744
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001745 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
Mat Martineau18a48e72012-05-17 20:53:34 -07001746 control->final = 1;
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001747
Mat Martineau18a48e72012-05-17 20:53:34 -07001748 control->reqseq = chan->buffer_seq;
1749 chan->last_acked_seq = chan->buffer_seq;
1750 control->txseq = chan->next_tx_seq;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001751
Mat Martineau18a48e72012-05-17 20:53:34 -07001752 __pack_control(chan, control, skb);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001753
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001754 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau18a48e72012-05-17 20:53:34 -07001755 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1756 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001757 }
1758
Mat Martineau18a48e72012-05-17 20:53:34 -07001759 /* Clone after data has been modified. Data is assumed to be
1760 read-only (for locking purposes) on cloned sk_buffs.
1761 */
1762 tx_skb = skb_clone(skb, GFP_KERNEL);
1763
1764 if (!tx_skb)
1765 break;
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -03001766
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001767 __set_retrans_timer(chan);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001768
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001769 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau18a48e72012-05-17 20:53:34 -07001770 chan->unacked_frames++;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03001771 chan->frames_sent++;
Mat Martineau18a48e72012-05-17 20:53:34 -07001772 sent++;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001773
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001774 if (skb_queue_is_last(&chan->tx_q, skb))
1775 chan->tx_send_head = NULL;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001776 else
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -03001777 chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
Mat Martineau18a48e72012-05-17 20:53:34 -07001778
1779 l2cap_do_send(chan, tx_skb);
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001780 BT_DBG("Sent txseq %u", control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001781 }
1782
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001783 BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
1784 chan->unacked_frames, skb_queue_len(&chan->tx_q));
Mat Martineau18a48e72012-05-17 20:53:34 -07001785
1786 return sent;
Gustavo F. Padovan9e917af2010-05-01 16:15:37 -03001787}
1788
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001789static void l2cap_ertm_resend(struct l2cap_chan *chan)
1790{
1791 struct l2cap_ctrl control;
1792 struct sk_buff *skb;
1793 struct sk_buff *tx_skb;
1794 u16 seq;
1795
1796 BT_DBG("chan %p", chan);
1797
1798 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1799 return;
1800
1801 while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
1802 seq = l2cap_seq_list_pop(&chan->retrans_list);
1803
1804 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
1805 if (!skb) {
1806 BT_DBG("Error: Can't retransmit seq %d, frame missing",
Gustavo Padovan2d792812012-10-06 10:07:01 +01001807 seq);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001808 continue;
1809 }
1810
1811 bt_cb(skb)->control.retries++;
1812 control = bt_cb(skb)->control;
1813
1814 if (chan->max_tx != 0 &&
1815 bt_cb(skb)->control.retries > chan->max_tx) {
1816 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
1817 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
1818 l2cap_seq_list_clear(&chan->retrans_list);
1819 break;
1820 }
1821
1822 control.reqseq = chan->buffer_seq;
1823 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
1824 control.final = 1;
1825 else
1826 control.final = 0;
1827
1828 if (skb_cloned(skb)) {
1829 /* Cloned sk_buffs are read-only, so we need a
1830 * writeable copy
1831 */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001832 tx_skb = skb_copy(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001833 } else {
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03001834 tx_skb = skb_clone(skb, GFP_KERNEL);
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001835 }
1836
1837 if (!tx_skb) {
1838 l2cap_seq_list_clear(&chan->retrans_list);
1839 break;
1840 }
1841
1842 /* Update skb contents */
1843 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
1844 put_unaligned_le32(__pack_extended_control(&control),
1845 tx_skb->data + L2CAP_HDR_SIZE);
1846 } else {
1847 put_unaligned_le16(__pack_enhanced_control(&control),
1848 tx_skb->data + L2CAP_HDR_SIZE);
1849 }
1850
1851 if (chan->fcs == L2CAP_FCS_CRC16) {
1852 u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len);
1853 put_unaligned_le16(fcs, skb_put(tx_skb,
1854 L2CAP_FCS_SIZE));
1855 }
1856
1857 l2cap_do_send(chan, tx_skb);
1858
1859 BT_DBG("Resent txseq %d", control.txseq);
1860
1861 chan->last_acked_seq = chan->buffer_seq;
1862 }
1863}
1864
Mat Martineauf80842a2012-05-17 20:53:46 -07001865static void l2cap_retransmit(struct l2cap_chan *chan,
1866 struct l2cap_ctrl *control)
1867{
1868 BT_DBG("chan %p, control %p", chan, control);
1869
1870 l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
1871 l2cap_ertm_resend(chan);
1872}
1873
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001874static void l2cap_retransmit_all(struct l2cap_chan *chan,
1875 struct l2cap_ctrl *control)
1876{
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001877 struct sk_buff *skb;
1878
1879 BT_DBG("chan %p, control %p", chan, control);
1880
1881 if (control->poll)
1882 set_bit(CONN_SEND_FBIT, &chan->conn_state);
1883
1884 l2cap_seq_list_clear(&chan->retrans_list);
1885
1886 if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
1887 return;
1888
1889 if (chan->unacked_frames) {
1890 skb_queue_walk(&chan->tx_q, skb) {
1891 if (bt_cb(skb)->control.txseq == control->reqseq ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01001892 skb == chan->tx_send_head)
Mat Martineaue1fbd4c2012-05-17 20:53:43 -07001893 break;
1894 }
1895
1896 skb_queue_walk_from(&chan->tx_q, skb) {
1897 if (skb == chan->tx_send_head)
1898 break;
1899
1900 l2cap_seq_list_append(&chan->retrans_list,
1901 bt_cb(skb)->control.txseq);
1902 }
1903
1904 l2cap_ertm_resend(chan);
1905 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07001906}
1907
Szymon Jancb17e73b2012-01-11 10:59:47 +01001908static void l2cap_send_ack(struct l2cap_chan *chan)
1909{
Mat Martineau0a0aba42012-05-17 20:53:39 -07001910 struct l2cap_ctrl control;
1911 u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
1912 chan->last_acked_seq);
1913 int threshold;
1914
1915 BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
1916 chan, chan->last_acked_seq, chan->buffer_seq);
1917
1918 memset(&control, 0, sizeof(control));
1919 control.sframe = 1;
1920
1921 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
1922 chan->rx_state == L2CAP_RX_STATE_RECV) {
1923 __clear_ack_timer(chan);
1924 control.super = L2CAP_SUPER_RNR;
1925 control.reqseq = chan->buffer_seq;
1926 l2cap_send_sframe(chan, &control);
1927 } else {
1928 if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
1929 l2cap_ertm_send(chan);
1930 /* If any i-frames were sent, they included an ack */
1931 if (chan->buffer_seq == chan->last_acked_seq)
1932 frames_to_ack = 0;
1933 }
1934
Mat Martineauc20f8e32012-07-10 05:47:07 -07001935 /* Ack now if the window is 3/4ths full.
Mat Martineau0a0aba42012-05-17 20:53:39 -07001936 * Calculate without mul or div
1937 */
Mat Martineauc20f8e32012-07-10 05:47:07 -07001938 threshold = chan->ack_win;
Mat Martineau0a0aba42012-05-17 20:53:39 -07001939 threshold += threshold << 1;
1940 threshold >>= 2;
1941
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03001942 BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
Mat Martineau0a0aba42012-05-17 20:53:39 -07001943 threshold);
1944
1945 if (frames_to_ack >= threshold) {
1946 __clear_ack_timer(chan);
1947 control.super = L2CAP_SUPER_RR;
1948 control.reqseq = chan->buffer_seq;
1949 l2cap_send_sframe(chan, &control);
1950 frames_to_ack = 0;
1951 }
1952
1953 if (frames_to_ack)
1954 __set_ack_timer(chan);
1955 }
Szymon Jancb17e73b2012-01-11 10:59:47 +01001956}
1957
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001958static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
1959 struct msghdr *msg, int len,
1960 int count, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961{
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02001962 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001963 struct sk_buff **frag;
Gustavo Padovan90338942012-04-06 20:15:47 -03001964 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965
Gustavo F. Padovan59203a22010-05-01 16:15:43 -03001966 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001967 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001968
1969 sent += count;
1970 len -= count;
1971
1972 /* Continuation fragments (no L2CAP header) */
1973 frag = &skb_shinfo(skb)->frag_list;
1974 while (len) {
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001975 struct sk_buff *tmp;
1976
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977 count = min_t(unsigned int, conn->mtu, len);
1978
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001979 tmp = chan->ops->alloc_skb(chan, count,
1980 msg->msg_flags & MSG_DONTWAIT);
1981 if (IS_ERR(tmp))
1982 return PTR_ERR(tmp);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02001983
Gustavo Padovanfbe00702012-05-15 13:22:55 -03001984 *frag = tmp;
1985
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001986 if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
1987 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001988
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02001989 (*frag)->priority = skb->priority;
1990
Linus Torvalds1da177e2005-04-16 15:20:36 -07001991 sent += count;
1992 len -= count;
1993
Gustavo Padovan2d0ed3d2012-05-11 13:16:12 -03001994 skb->len += (*frag)->len;
1995 skb->data_len += (*frag)->len;
1996
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997 frag = &(*frag)->next;
1998 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001999
2000 return sent;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002001}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002002
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002003static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002004 struct msghdr *msg, size_t len,
2005 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002006{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002007 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002008 struct sk_buff *skb;
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002009 int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002010 struct l2cap_hdr *lh;
2011
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002012 BT_DBG("chan %p len %zu priority %u", chan, len, priority);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002013
2014 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002015
2016 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002017 msg->msg_flags & MSG_DONTWAIT);
2018 if (IS_ERR(skb))
2019 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002020
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002021 skb->priority = priority;
2022
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002023 /* Create L2CAP header */
2024 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002025 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenkodaf6a78c2012-05-03 10:55:52 +03002026 lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
2027 put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002028
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002029 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002030 if (unlikely(err < 0)) {
2031 kfree_skb(skb);
2032 return ERR_PTR(err);
2033 }
2034 return skb;
2035}
2036
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002037static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002038 struct msghdr *msg, size_t len,
2039 u32 priority)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002040{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002041 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002042 struct sk_buff *skb;
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002043 int err, count;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002044 struct l2cap_hdr *lh;
2045
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002046 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002047
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002048 count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002049
Gustavo Padovanf2ba7fa2012-05-03 04:54:21 -03002050 skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
Gustavo Padovan90338942012-04-06 20:15:47 -03002051 msg->msg_flags & MSG_DONTWAIT);
2052 if (IS_ERR(skb))
2053 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002054
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002055 skb->priority = priority;
2056
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002057 /* Create L2CAP header */
2058 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002059 lh->cid = cpu_to_le16(chan->dcid);
Gustavo Padovan6ff9b5e2012-05-02 11:56:17 -03002060 lh->len = cpu_to_le16(len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002061
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002062 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002063 if (unlikely(err < 0)) {
2064 kfree_skb(skb);
2065 return ERR_PTR(err);
2066 }
2067 return skb;
2068}
2069
Luiz Augusto von Dentzab0ff762011-09-12 20:00:50 +03002070static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002071 struct msghdr *msg, size_t len,
2072 u16 sdulen)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002073{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002074 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002075 struct sk_buff *skb;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002076 int err, count, hlen;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002077 struct l2cap_hdr *lh;
2078
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002079 BT_DBG("chan %p len %zu", chan, len);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002080
Gustavo F. Padovan0ee0d202010-05-01 16:15:41 -03002081 if (!conn)
2082 return ERR_PTR(-ENOTCONN);
2083
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002084 hlen = __ertm_hdr_size(chan);
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002085
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002086 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002087 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002088
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002089 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002090 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002091
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002092 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002093
2094 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002095 msg->msg_flags & MSG_DONTWAIT);
2096 if (IS_ERR(skb))
2097 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002098
2099 /* Create L2CAP header */
2100 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002101 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002102 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002103
Mat Martineau18a48e72012-05-17 20:53:34 -07002104 /* Control header is populated later */
2105 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2106 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2107 else
2108 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002109
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002110 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002111 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002112
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002113 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002114 if (unlikely(err < 0)) {
2115 kfree_skb(skb);
2116 return ERR_PTR(err);
2117 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002118
Mat Martineau18a48e72012-05-17 20:53:34 -07002119 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002120 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002121 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002122}
2123
Mat Martineau94122bb2012-05-02 09:42:02 -07002124static int l2cap_segment_sdu(struct l2cap_chan *chan,
2125 struct sk_buff_head *seg_queue,
2126 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002127{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002128 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002129 u16 sdu_len;
2130 size_t pdu_len;
Mat Martineau94122bb2012-05-02 09:42:02 -07002131 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002132
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002133 BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002134
Mat Martineau94122bb2012-05-02 09:42:02 -07002135 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2136 * so fragmented skbs are not used. The HCI layer's handling
2137 * of fragmented skbs is not compatible with ERTM's queueing.
2138 */
2139
2140 /* PDU size is derived from the HCI MTU */
2141 pdu_len = chan->conn->mtu;
2142
2143 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
2144
2145 /* Adjust for largest possible L2CAP overhead. */
Gustavo Padovan35d401d2012-05-25 18:57:05 -03002146 if (chan->fcs)
2147 pdu_len -= L2CAP_FCS_SIZE;
2148
Gustavo Padovanba7aa642012-05-29 13:29:16 -03002149 pdu_len -= __ertm_hdr_size(chan);
Mat Martineau94122bb2012-05-02 09:42:02 -07002150
2151 /* Remote device may have requested smaller PDUs */
2152 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2153
2154 if (len <= pdu_len) {
2155 sar = L2CAP_SAR_UNSEGMENTED;
2156 sdu_len = 0;
2157 pdu_len = len;
2158 } else {
2159 sar = L2CAP_SAR_START;
2160 sdu_len = len;
2161 pdu_len -= L2CAP_SDULEN_SIZE;
2162 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002163
2164 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002165 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002166
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002167 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002168 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002169 return PTR_ERR(skb);
2170 }
2171
Mat Martineau94122bb2012-05-02 09:42:02 -07002172 bt_cb(skb)->control.sar = sar;
2173 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002174
Mat Martineau94122bb2012-05-02 09:42:02 -07002175 len -= pdu_len;
2176 if (sdu_len) {
2177 sdu_len = 0;
2178 pdu_len += L2CAP_SDULEN_SIZE;
2179 }
2180
2181 if (len <= pdu_len) {
2182 sar = L2CAP_SAR_END;
2183 pdu_len = len;
2184 } else {
2185 sar = L2CAP_SAR_CONTINUE;
2186 }
2187 }
2188
Gustavo Padovanf0f62792012-05-29 13:29:17 -03002189 return 0;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002190}
2191
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002192int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002193 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002194{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002195 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002196 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002197 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002198
2199 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002200 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002201 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002202 if (IS_ERR(skb))
2203 return PTR_ERR(skb);
2204
2205 l2cap_do_send(chan, skb);
2206 return len;
2207 }
2208
2209 switch (chan->mode) {
2210 case L2CAP_MODE_BASIC:
2211 /* Check outgoing MTU */
2212 if (len > chan->omtu)
2213 return -EMSGSIZE;
2214
2215 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002216 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002217 if (IS_ERR(skb))
2218 return PTR_ERR(skb);
2219
2220 l2cap_do_send(chan, skb);
2221 err = len;
2222 break;
2223
2224 case L2CAP_MODE_ERTM:
2225 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002226 /* Check outgoing MTU */
2227 if (len > chan->omtu) {
2228 err = -EMSGSIZE;
2229 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002230 }
2231
Mat Martineau94122bb2012-05-02 09:42:02 -07002232 __skb_queue_head_init(&seg_queue);
2233
2234 /* Do segmentation before calling in to the state machine,
2235 * since it's possible to block while waiting for memory
2236 * allocation.
2237 */
2238 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2239
2240 /* The channel could have been closed while segmenting,
2241 * check that it is still connected.
2242 */
2243 if (chan->state != BT_CONNECTED) {
2244 __skb_queue_purge(&seg_queue);
2245 err = -ENOTCONN;
2246 }
2247
2248 if (err)
2249 break;
2250
Mat Martineau37339372012-05-17 20:53:33 -07002251 if (chan->mode == L2CAP_MODE_ERTM)
Gustavo Padovand6603662012-05-21 13:58:22 -03002252 l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002253 else
Gustavo Padovand6603662012-05-21 13:58:22 -03002254 l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002255
Gustavo Padovand6603662012-05-21 13:58:22 -03002256 err = len;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002257
Mat Martineau94122bb2012-05-02 09:42:02 -07002258 /* If the skbs were not queued for sending, they'll still be in
2259 * seg_queue and need to be purged.
2260 */
2261 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002262 break;
2263
2264 default:
2265 BT_DBG("bad state %1.1x", chan->mode);
2266 err = -EBADFD;
2267 }
2268
2269 return err;
2270}
2271
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002272static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2273{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002274 struct l2cap_ctrl control;
2275 u16 seq;
2276
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002277 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002278
2279 memset(&control, 0, sizeof(control));
2280 control.sframe = 1;
2281 control.super = L2CAP_SUPER_SREJ;
2282
2283 for (seq = chan->expected_tx_seq; seq != txseq;
2284 seq = __next_seq(chan, seq)) {
2285 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2286 control.reqseq = seq;
2287 l2cap_send_sframe(chan, &control);
2288 l2cap_seq_list_append(&chan->srej_list, seq);
2289 }
2290 }
2291
2292 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002293}
2294
2295static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2296{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002297 struct l2cap_ctrl control;
2298
2299 BT_DBG("chan %p", chan);
2300
2301 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2302 return;
2303
2304 memset(&control, 0, sizeof(control));
2305 control.sframe = 1;
2306 control.super = L2CAP_SUPER_SREJ;
2307 control.reqseq = chan->srej_list.tail;
2308 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002309}
2310
2311static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2312{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002313 struct l2cap_ctrl control;
2314 u16 initial_head;
2315 u16 seq;
2316
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002317 BT_DBG("chan %p, txseq %u", chan, txseq);
Mat Martineaubed68bd2012-05-17 20:53:44 -07002318
2319 memset(&control, 0, sizeof(control));
2320 control.sframe = 1;
2321 control.super = L2CAP_SUPER_SREJ;
2322
2323 /* Capture initial list head to allow only one pass through the list. */
2324 initial_head = chan->srej_list.head;
2325
2326 do {
2327 seq = l2cap_seq_list_pop(&chan->srej_list);
2328 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2329 break;
2330
2331 control.reqseq = seq;
2332 l2cap_send_sframe(chan, &control);
2333 l2cap_seq_list_append(&chan->srej_list, seq);
2334 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002335}
2336
Mat Martineau608bcc62012-05-17 20:53:32 -07002337static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2338{
2339 struct sk_buff *acked_skb;
2340 u16 ackseq;
2341
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002342 BT_DBG("chan %p, reqseq %u", chan, reqseq);
Mat Martineau608bcc62012-05-17 20:53:32 -07002343
2344 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2345 return;
2346
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002347 BT_DBG("expected_ack_seq %u, unacked_frames %u",
Mat Martineau608bcc62012-05-17 20:53:32 -07002348 chan->expected_ack_seq, chan->unacked_frames);
2349
2350 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2351 ackseq = __next_seq(chan, ackseq)) {
2352
2353 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2354 if (acked_skb) {
2355 skb_unlink(acked_skb, &chan->tx_q);
2356 kfree_skb(acked_skb);
2357 chan->unacked_frames--;
2358 }
2359 }
2360
2361 chan->expected_ack_seq = reqseq;
2362
2363 if (chan->unacked_frames == 0)
2364 __clear_retrans_timer(chan);
2365
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002366 BT_DBG("unacked_frames %u", chan->unacked_frames);
Mat Martineau608bcc62012-05-17 20:53:32 -07002367}
2368
2369static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2370{
2371 BT_DBG("chan %p", chan);
2372
2373 chan->expected_tx_seq = chan->buffer_seq;
2374 l2cap_seq_list_clear(&chan->srej_list);
2375 skb_queue_purge(&chan->srej_q);
2376 chan->rx_state = L2CAP_RX_STATE_RECV;
2377}
2378
Gustavo Padovand6603662012-05-21 13:58:22 -03002379static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
2380 struct l2cap_ctrl *control,
2381 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002382{
Mat Martineau608bcc62012-05-17 20:53:32 -07002383 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2384 event);
2385
2386 switch (event) {
2387 case L2CAP_EV_DATA_REQUEST:
2388 if (chan->tx_send_head == NULL)
2389 chan->tx_send_head = skb_peek(skbs);
2390
2391 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2392 l2cap_ertm_send(chan);
2393 break;
2394 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2395 BT_DBG("Enter LOCAL_BUSY");
2396 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2397
2398 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2399 /* The SREJ_SENT state must be aborted if we are to
2400 * enter the LOCAL_BUSY state.
2401 */
2402 l2cap_abort_rx_srej_sent(chan);
2403 }
2404
2405 l2cap_send_ack(chan);
2406
2407 break;
2408 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2409 BT_DBG("Exit LOCAL_BUSY");
2410 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2411
2412 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2413 struct l2cap_ctrl local_control;
2414
2415 memset(&local_control, 0, sizeof(local_control));
2416 local_control.sframe = 1;
2417 local_control.super = L2CAP_SUPER_RR;
2418 local_control.poll = 1;
2419 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002420 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002421
2422 chan->retry_count = 1;
2423 __set_monitor_timer(chan);
2424 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2425 }
2426 break;
2427 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2428 l2cap_process_reqseq(chan, control->reqseq);
2429 break;
2430 case L2CAP_EV_EXPLICIT_POLL:
2431 l2cap_send_rr_or_rnr(chan, 1);
2432 chan->retry_count = 1;
2433 __set_monitor_timer(chan);
2434 __clear_ack_timer(chan);
2435 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2436 break;
2437 case L2CAP_EV_RETRANS_TO:
2438 l2cap_send_rr_or_rnr(chan, 1);
2439 chan->retry_count = 1;
2440 __set_monitor_timer(chan);
2441 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2442 break;
2443 case L2CAP_EV_RECV_FBIT:
2444 /* Nothing to process */
2445 break;
2446 default:
2447 break;
2448 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002449}
2450
Gustavo Padovand6603662012-05-21 13:58:22 -03002451static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2452 struct l2cap_ctrl *control,
2453 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002454{
Mat Martineau608bcc62012-05-17 20:53:32 -07002455 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2456 event);
2457
2458 switch (event) {
2459 case L2CAP_EV_DATA_REQUEST:
2460 if (chan->tx_send_head == NULL)
2461 chan->tx_send_head = skb_peek(skbs);
2462 /* Queue data, but don't send. */
2463 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2464 break;
2465 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2466 BT_DBG("Enter LOCAL_BUSY");
2467 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2468
2469 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2470 /* The SREJ_SENT state must be aborted if we are to
2471 * enter the LOCAL_BUSY state.
2472 */
2473 l2cap_abort_rx_srej_sent(chan);
2474 }
2475
2476 l2cap_send_ack(chan);
2477
2478 break;
2479 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2480 BT_DBG("Exit LOCAL_BUSY");
2481 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2482
2483 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2484 struct l2cap_ctrl local_control;
2485 memset(&local_control, 0, sizeof(local_control));
2486 local_control.sframe = 1;
2487 local_control.super = L2CAP_SUPER_RR;
2488 local_control.poll = 1;
2489 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002490 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002491
2492 chan->retry_count = 1;
2493 __set_monitor_timer(chan);
2494 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2495 }
2496 break;
2497 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2498 l2cap_process_reqseq(chan, control->reqseq);
2499
2500 /* Fall through */
2501
2502 case L2CAP_EV_RECV_FBIT:
2503 if (control && control->final) {
2504 __clear_monitor_timer(chan);
2505 if (chan->unacked_frames > 0)
2506 __set_retrans_timer(chan);
2507 chan->retry_count = 0;
2508 chan->tx_state = L2CAP_TX_STATE_XMIT;
2509 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2510 }
2511 break;
2512 case L2CAP_EV_EXPLICIT_POLL:
2513 /* Ignore */
2514 break;
2515 case L2CAP_EV_MONITOR_TO:
2516 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2517 l2cap_send_rr_or_rnr(chan, 1);
2518 __set_monitor_timer(chan);
2519 chan->retry_count++;
2520 } else {
2521 l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
2522 }
2523 break;
2524 default:
2525 break;
2526 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002527}
2528
Gustavo Padovand6603662012-05-21 13:58:22 -03002529static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2530 struct sk_buff_head *skbs, u8 event)
Mat Martineau608bcc62012-05-17 20:53:32 -07002531{
Mat Martineau608bcc62012-05-17 20:53:32 -07002532 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2533 chan, control, skbs, event, chan->tx_state);
2534
2535 switch (chan->tx_state) {
2536 case L2CAP_TX_STATE_XMIT:
Gustavo Padovand6603662012-05-21 13:58:22 -03002537 l2cap_tx_state_xmit(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002538 break;
2539 case L2CAP_TX_STATE_WAIT_F:
Gustavo Padovand6603662012-05-21 13:58:22 -03002540 l2cap_tx_state_wait_f(chan, control, skbs, event);
Mat Martineau608bcc62012-05-17 20:53:32 -07002541 break;
2542 default:
2543 /* Ignore event */
2544 break;
2545 }
Mat Martineau608bcc62012-05-17 20:53:32 -07002546}
2547
Mat Martineau4b51dae92012-05-17 20:53:37 -07002548static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2549 struct l2cap_ctrl *control)
2550{
2551 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002552 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
Mat Martineau4b51dae92012-05-17 20:53:37 -07002553}
2554
Mat Martineauf80842a2012-05-17 20:53:46 -07002555static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2556 struct l2cap_ctrl *control)
2557{
2558 BT_DBG("chan %p, control %p", chan, control);
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03002559 l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
Mat Martineauf80842a2012-05-17 20:53:46 -07002560}
2561
Linus Torvalds1da177e2005-04-16 15:20:36 -07002562/* Copy frame to all raw sockets on that connection */
2563static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2564{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002565 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002566 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567
2568 BT_DBG("conn %p", conn);
2569
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002570 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002571
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002572 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002573 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002574 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002575 continue;
2576
2577 /* Don't send frame to the socket it came from */
2578 if (skb->sk == sk)
2579 continue;
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002580 nskb = skb_clone(skb, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002581 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002582 continue;
2583
Gustavo Padovan80b98022012-05-27 22:27:51 -03002584 if (chan->ops->recv(chan, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002585 kfree_skb(nskb);
2586 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002587
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002588 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002589}
2590
2591/* ---- L2CAP signalling commands ---- */
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002592static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2593 u8 ident, u16 dlen, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002594{
2595 struct sk_buff *skb, **frag;
2596 struct l2cap_cmd_hdr *cmd;
2597 struct l2cap_hdr *lh;
2598 int len, count;
2599
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002600 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
2601 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002602
2603 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2604 count = min_t(unsigned int, conn->mtu, len);
2605
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002606 skb = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002607 if (!skb)
2608 return NULL;
2609
2610 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002611 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002612
2613 if (conn->hcon->type == LE_LINK)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002614 lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002615 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002616 lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002617
2618 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2619 cmd->code = code;
2620 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002621 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002622
2623 if (dlen) {
2624 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2625 memcpy(skb_put(skb, count), data, count);
2626 data += count;
2627 }
2628
2629 len -= skb->len;
2630
2631 /* Continuation fragments (no L2CAP header) */
2632 frag = &skb_shinfo(skb)->frag_list;
2633 while (len) {
2634 count = min_t(unsigned int, conn->mtu, len);
2635
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03002636 *frag = bt_skb_alloc(count, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002637 if (!*frag)
2638 goto fail;
2639
2640 memcpy(skb_put(*frag, count), data, count);
2641
2642 len -= count;
2643 data += count;
2644
2645 frag = &(*frag)->next;
2646 }
2647
2648 return skb;
2649
2650fail:
2651 kfree_skb(skb);
2652 return NULL;
2653}
2654
Gustavo Padovan2d792812012-10-06 10:07:01 +01002655static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
2656 unsigned long *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002657{
2658 struct l2cap_conf_opt *opt = *ptr;
2659 int len;
2660
2661 len = L2CAP_CONF_OPT_SIZE + opt->len;
2662 *ptr += len;
2663
2664 *type = opt->type;
2665 *olen = opt->len;
2666
2667 switch (opt->len) {
2668 case 1:
2669 *val = *((u8 *) opt->val);
2670 break;
2671
2672 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002673 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002674 break;
2675
2676 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002677 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002678 break;
2679
2680 default:
2681 *val = (unsigned long) opt->val;
2682 break;
2683 }
2684
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002685 BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002686 return len;
2687}
2688
Linus Torvalds1da177e2005-04-16 15:20:36 -07002689static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2690{
2691 struct l2cap_conf_opt *opt = *ptr;
2692
Andrei Emeltchenkob4400672012-07-10 15:27:49 +03002693 BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002694
2695 opt->type = type;
2696 opt->len = len;
2697
2698 switch (len) {
2699 case 1:
2700 *((u8 *) opt->val) = val;
2701 break;
2702
2703 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002704 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002705 break;
2706
2707 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002708 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002709 break;
2710
2711 default:
2712 memcpy(opt->val, (void *) val, len);
2713 break;
2714 }
2715
2716 *ptr += L2CAP_CONF_OPT_SIZE + len;
2717}
2718
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002719static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2720{
2721 struct l2cap_conf_efs efs;
2722
Szymon Janc1ec918c2011-11-16 09:32:21 +01002723 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002724 case L2CAP_MODE_ERTM:
2725 efs.id = chan->local_id;
2726 efs.stype = chan->local_stype;
2727 efs.msdu = cpu_to_le16(chan->local_msdu);
2728 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03002729 efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002730 efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002731 break;
2732
2733 case L2CAP_MODE_STREAMING:
2734 efs.id = 1;
2735 efs.stype = L2CAP_SERV_BESTEFFORT;
2736 efs.msdu = cpu_to_le16(chan->local_msdu);
2737 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2738 efs.acc_lat = 0;
2739 efs.flush_to = 0;
2740 break;
2741
2742 default:
2743 return;
2744 }
2745
2746 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
Andrei Emeltchenko8936fa62012-10-08 11:14:41 +03002747 (unsigned long) &efs);
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002748}
2749
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002750static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002751{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002752 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau03625202012-05-17 20:53:51 -07002753 ack_timer.work);
2754 u16 frames_to_ack;
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002755
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02002756 BT_DBG("chan %p", chan);
2757
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002758 l2cap_chan_lock(chan);
2759
Mat Martineau03625202012-05-17 20:53:51 -07002760 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
2761 chan->last_acked_seq);
2762
2763 if (frames_to_ack)
2764 l2cap_send_rr_or_rnr(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002765
2766 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01002767 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002768}
2769
Andrei Emeltchenko466f8002012-05-29 13:59:01 +03002770int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002771{
Mat Martineau3c588192012-04-11 10:48:42 -07002772 int err;
2773
Mat Martineau105bdf92012-04-27 16:50:48 -07002774 chan->next_tx_seq = 0;
2775 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002776 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002777 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002778 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002779 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07002780 chan->last_acked_seq = 0;
2781 chan->sdu = NULL;
2782 chan->sdu_last_frag = NULL;
2783 chan->sdu_len = 0;
2784
Mat Martineaud34c34f2012-05-14 14:49:27 -07002785 skb_queue_head_init(&chan->tx_q);
2786
Mat Martineau105bdf92012-04-27 16:50:48 -07002787 if (chan->mode != L2CAP_MODE_ERTM)
2788 return 0;
2789
2790 chan->rx_state = L2CAP_RX_STATE_RECV;
2791 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002792
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002793 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
2794 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
2795 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002796
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03002797 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002798
Mat Martineau3c588192012-04-11 10:48:42 -07002799 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
2800 if (err < 0)
2801 return err;
2802
Mat Martineau9dc9aff2012-05-17 16:20:14 -07002803 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
2804 if (err < 0)
2805 l2cap_seq_list_free(&chan->srej_list);
2806
2807 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002808}
2809
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002810static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2811{
2812 switch (mode) {
2813 case L2CAP_MODE_STREAMING:
2814 case L2CAP_MODE_ERTM:
2815 if (l2cap_mode_supported(mode, remote_feat_mask))
2816 return mode;
2817 /* fall through */
2818 default:
2819 return L2CAP_MODE_BASIC;
2820 }
2821}
2822
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002823static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
2824{
2825 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
2826}
2827
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002828static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
2829{
2830 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
2831}
2832
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002833static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
2834{
2835 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01002836 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002837 /* use extended control field */
2838 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002839 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
2840 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002841 chan->tx_win = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002842 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002843 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
2844 }
Mat Martineauc20f8e32012-07-10 05:47:07 -07002845 chan->ack_win = chan->tx_win;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002846}
2847
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03002848static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002849{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002850 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002851 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002852 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002853 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002854
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03002855 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002856
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002857 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002858 goto done;
2859
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002860 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002861 case L2CAP_MODE_STREAMING:
2862 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002863 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002864 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002865
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002866 if (__l2cap_efs_supported(chan))
2867 set_bit(FLAG_EFS_ENABLE, &chan->flags);
2868
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002869 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002870 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002871 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002872 break;
2873 }
2874
2875done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002876 if (chan->imtu != L2CAP_DEFAULT_MTU)
2877 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02002878
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002879 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002880 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002881 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01002882 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002883 break;
2884
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002885 rfc.mode = L2CAP_MODE_BASIC;
2886 rfc.txwin_size = 0;
2887 rfc.max_transmit = 0;
2888 rfc.retrans_timeout = 0;
2889 rfc.monitor_timeout = 0;
2890 rfc.max_pdu_size = 0;
2891
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002892 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01002893 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002894 break;
2895
2896 case L2CAP_MODE_ERTM:
2897 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002898 rfc.max_transmit = chan->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002899 rfc.retrans_timeout = 0;
2900 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002901
2902 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01002903 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
2904 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002905 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002906
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002907 l2cap_txwin_setup(chan);
2908
2909 rfc.txwin_size = min_t(u16, chan->tx_win,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002910 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002911
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002912 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01002913 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002914
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002915 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2916 l2cap_add_opt_efs(&ptr, chan);
2917
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002918 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002919 break;
2920
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002921 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002922 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002923 chan->fcs = L2CAP_FCS_NONE;
2924 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002925 }
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002926
2927 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2928 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Gustavo Padovan2d792812012-10-06 10:07:01 +01002929 chan->tx_win);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002930 break;
2931
2932 case L2CAP_MODE_STREAMING:
Mat Martineau273759e2012-05-17 20:53:53 -07002933 l2cap_txwin_setup(chan);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002934 rfc.mode = L2CAP_MODE_STREAMING;
2935 rfc.txwin_size = 0;
2936 rfc.max_transmit = 0;
2937 rfc.retrans_timeout = 0;
2938 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002939
2940 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
Gustavo Padovan2d792812012-10-06 10:07:01 +01002941 L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
2942 L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002943 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002944
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002945 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
Gustavo Padovan2d792812012-10-06 10:07:01 +01002946 (unsigned long) &rfc);
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002947
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002948 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2949 l2cap_add_opt_efs(&ptr, chan);
2950
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002951 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002952 break;
2953
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002954 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01002955 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002956 chan->fcs = L2CAP_FCS_NONE;
2957 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002958 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002959 break;
2960 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002961
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002962 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03002963 req->flags = __constant_cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002964
2965 return ptr - data;
2966}
2967
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002968static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002969{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002970 struct l2cap_conf_rsp *rsp = data;
2971 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002972 void *req = chan->conf_req;
2973 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002974 int type, hint, olen;
2975 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002976 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002977 struct l2cap_conf_efs efs;
2978 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02002979 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002980 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002981 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002982
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002983 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002984
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002985 while (len >= L2CAP_CONF_OPT_SIZE) {
2986 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002987
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002988 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002989 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002990
2991 switch (type) {
2992 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02002993 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002994 break;
2995
2996 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002997 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002998 break;
2999
3000 case L2CAP_CONF_QOS:
3001 break;
3002
Marcel Holtmann6464f352007-10-20 13:39:51 +02003003 case L2CAP_CONF_RFC:
3004 if (olen == sizeof(rfc))
3005 memcpy(&rfc, (void *) val, olen);
3006 break;
3007
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003008 case L2CAP_CONF_FCS:
3009 if (val == L2CAP_FCS_NONE)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003010 set_bit(CONF_NO_FCS_RECV, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003011 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003012
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003013 case L2CAP_CONF_EFS:
3014 remote_efs = 1;
3015 if (olen == sizeof(efs))
3016 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003017 break;
3018
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003019 case L2CAP_CONF_EWS:
3020 if (!enable_hs)
3021 return -ECONNREFUSED;
3022
3023 set_bit(FLAG_EXT_CTRL, &chan->flags);
3024 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003025 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003026 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003027 break;
3028
3029 default:
3030 if (hint)
3031 break;
3032
3033 result = L2CAP_CONF_UNKNOWN;
3034 *((u8 *) ptr++) = type;
3035 break;
3036 }
3037 }
3038
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003039 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003040 goto done;
3041
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003042 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003043 case L2CAP_MODE_STREAMING:
3044 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003045 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003046 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003047 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003048 break;
3049 }
3050
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003051 if (remote_efs) {
3052 if (__l2cap_efs_supported(chan))
3053 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3054 else
3055 return -ECONNREFUSED;
3056 }
3057
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003058 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003059 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003060
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003061 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003062 }
3063
3064done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003065 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003066 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003067 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003068
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003069 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003070 return -ECONNREFUSED;
3071
Gustavo Padovan2d792812012-10-06 10:07:01 +01003072 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3073 (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003074 }
3075
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003076 if (result == L2CAP_CONF_SUCCESS) {
3077 /* Configure output options and let the other side know
3078 * which ones we don't like. */
3079
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003080 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3081 result = L2CAP_CONF_UNACCEPT;
3082 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003083 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003084 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003085 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003086 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003087
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003088 if (remote_efs) {
3089 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003090 efs.stype != L2CAP_SERV_NOTRAFIC &&
3091 efs.stype != chan->local_stype) {
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003092
3093 result = L2CAP_CONF_UNACCEPT;
3094
3095 if (chan->num_conf_req >= 1)
3096 return -ECONNREFUSED;
3097
3098 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003099 sizeof(efs),
3100 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003101 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003102 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003103 result = L2CAP_CONF_PENDING;
3104 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003105 }
3106 }
3107
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003108 switch (rfc.mode) {
3109 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003110 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003111 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003112 break;
3113
3114 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003115 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3116 chan->remote_tx_win = rfc.txwin_size;
3117 else
3118 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3119
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003120 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003121
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003122 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003123 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3124 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003125 rfc.max_pdu_size = cpu_to_le16(size);
3126 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003127
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003128 rfc.retrans_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003129 __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003130 rfc.monitor_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003131 __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003132
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003133 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003134
3135 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003136 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003137
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003138 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3139 chan->remote_id = efs.id;
3140 chan->remote_stype = efs.stype;
3141 chan->remote_msdu = le16_to_cpu(efs.msdu);
3142 chan->remote_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003143 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003144 chan->remote_acc_lat =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003145 le32_to_cpu(efs.acc_lat);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003146 chan->remote_sdu_itime =
3147 le32_to_cpu(efs.sdu_itime);
3148 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003149 sizeof(efs),
3150 (unsigned long) &efs);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003151 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003152 break;
3153
3154 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003155 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003156 chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
3157 L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003158 rfc.max_pdu_size = cpu_to_le16(size);
3159 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003160
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003161 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003162
Gustavo Padovan2d792812012-10-06 10:07:01 +01003163 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3164 (unsigned long) &rfc);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003165
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003166 break;
3167
3168 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003169 result = L2CAP_CONF_UNACCEPT;
3170
3171 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003172 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003173 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003174
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003175 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003176 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003177 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003178 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003179 rsp->result = cpu_to_le16(result);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003180 rsp->flags = __constant_cpu_to_le16(0);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003181
3182 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003183}
3184
Gustavo Padovan2d792812012-10-06 10:07:01 +01003185static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3186 void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003187{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003188 struct l2cap_conf_req *req = data;
3189 void *ptr = req->data;
3190 int type, olen;
3191 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003192 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003193 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003194
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003195 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003196
3197 while (len >= L2CAP_CONF_OPT_SIZE) {
3198 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3199
3200 switch (type) {
3201 case L2CAP_CONF_MTU:
3202 if (val < L2CAP_DEFAULT_MIN_MTU) {
3203 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003204 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003205 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003206 chan->imtu = val;
3207 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003208 break;
3209
3210 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003211 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003212 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003213 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003214 break;
3215
3216 case L2CAP_CONF_RFC:
3217 if (olen == sizeof(rfc))
3218 memcpy(&rfc, (void *)val, olen);
3219
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003220 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003221 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003222 return -ECONNREFUSED;
3223
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003224 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003225
3226 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003227 sizeof(rfc), (unsigned long) &rfc);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003228 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003229
3230 case L2CAP_CONF_EWS:
Mat Martineauc20f8e32012-07-10 05:47:07 -07003231 chan->ack_win = min_t(u16, val, chan->ack_win);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003232 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
Mat Martineauc20f8e32012-07-10 05:47:07 -07003233 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003234 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003235
3236 case L2CAP_CONF_EFS:
3237 if (olen == sizeof(efs))
3238 memcpy(&efs, (void *)val, olen);
3239
3240 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003241 efs.stype != L2CAP_SERV_NOTRAFIC &&
3242 efs.stype != chan->local_stype)
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003243 return -ECONNREFUSED;
3244
Gustavo Padovan2d792812012-10-06 10:07:01 +01003245 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3246 (unsigned long) &efs);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003247 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003248 }
3249 }
3250
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003251 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003252 return -ECONNREFUSED;
3253
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003254 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003255
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003256 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003257 switch (rfc.mode) {
3258 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003259 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3260 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3261 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003262 if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3263 chan->ack_win = min_t(u16, chan->ack_win,
3264 rfc.txwin_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003265
3266 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3267 chan->local_msdu = le16_to_cpu(efs.msdu);
3268 chan->local_sdu_itime =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003269 le32_to_cpu(efs.sdu_itime);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003270 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3271 chan->local_flush_to =
Gustavo Padovan2d792812012-10-06 10:07:01 +01003272 le32_to_cpu(efs.flush_to);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003273 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003274 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003275
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003276 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003277 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003278 }
3279 }
3280
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003281 req->dcid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003282 req->flags = __constant_cpu_to_le16(0);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003283
3284 return ptr - data;
3285}
3286
Gustavo Padovan2d792812012-10-06 10:07:01 +01003287static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
3288 u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003289{
3290 struct l2cap_conf_rsp *rsp = data;
3291 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003292
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003293 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003294
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003295 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003296 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003297 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003298
3299 return ptr - data;
3300}
3301
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003302void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003303{
3304 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003305 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003306 u8 buf[128];
3307
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003308 rsp.scid = cpu_to_le16(chan->dcid);
3309 rsp.dcid = cpu_to_le16(chan->scid);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003310 rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
3311 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Gustavo Padovan2d792812012-10-06 10:07:01 +01003312 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003313
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003314 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003315 return;
3316
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003317 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003318 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003319 chan->num_conf_req++;
3320}
3321
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003322static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003323{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003324 int type, olen;
3325 unsigned long val;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003326 /* Use sane default values in case a misbehaving remote device
3327 * did not send an RFC or extended window size option.
3328 */
3329 u16 txwin_ext = chan->ack_win;
3330 struct l2cap_conf_rfc rfc = {
3331 .mode = chan->mode,
3332 .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3333 .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3334 .max_pdu_size = cpu_to_le16(chan->imtu),
3335 .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3336 };
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003337
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003338 BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003339
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003340 if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003341 return;
3342
3343 while (len >= L2CAP_CONF_OPT_SIZE) {
3344 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3345
Mat Martineauc20f8e32012-07-10 05:47:07 -07003346 switch (type) {
3347 case L2CAP_CONF_RFC:
3348 if (olen == sizeof(rfc))
3349 memcpy(&rfc, (void *)val, olen);
Szymon Janc8f321f82012-06-08 11:33:33 +02003350 break;
Mat Martineauc20f8e32012-07-10 05:47:07 -07003351 case L2CAP_CONF_EWS:
3352 txwin_ext = val;
3353 break;
3354 }
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003355 }
3356
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003357 switch (rfc.mode) {
3358 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003359 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3360 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
Mat Martineauc20f8e32012-07-10 05:47:07 -07003361 chan->mps = le16_to_cpu(rfc.max_pdu_size);
3362 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3363 chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3364 else
3365 chan->ack_win = min_t(u16, chan->ack_win,
3366 rfc.txwin_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003367 break;
3368 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003369 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003370 }
3371}
3372
Gustavo Padovan2d792812012-10-06 10:07:01 +01003373static inline int l2cap_command_rej(struct l2cap_conn *conn,
3374 struct l2cap_cmd_hdr *cmd, u8 *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003375{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003376 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003377
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003378 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003379 return 0;
3380
3381 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003382 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003383 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003384
3385 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003386 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003387
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003388 l2cap_conn_start(conn);
3389 }
3390
3391 return 0;
3392}
3393
Gustavo Padovan300229f2012-10-12 19:40:40 +08003394static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
3395 u8 *data, u8 rsp_code, u8 amp_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003396{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003397 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3398 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003399 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003400 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003401 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003402
3403 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003404 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003405
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003406 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003407
3408 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003409 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003410 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003411 result = L2CAP_CR_BAD_PSM;
3412 goto sendresp;
3413 }
3414
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003415 parent = pchan->sk;
3416
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003417 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003418 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003419
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003420 /* Check if the ACL is secure enough (if not SDP) */
Andrei Emeltchenko2983fd62012-05-24 15:42:50 +03003421 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003422 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003423 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003424 result = L2CAP_CR_SEC_BLOCK;
3425 goto response;
3426 }
3427
Linus Torvalds1da177e2005-04-16 15:20:36 -07003428 result = L2CAP_CR_NO_MEM;
3429
Gustavo Padovan2dfa1002012-05-27 22:27:58 -03003430 /* Check if we already have channel with that dcid */
3431 if (__l2cap_get_chan_by_dcid(conn, scid))
3432 goto response;
3433
Gustavo Padovan80b98022012-05-27 22:27:51 -03003434 chan = pchan->ops->new_connection(pchan);
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003435 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003436 goto response;
3437
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003438 sk = chan->sk;
3439
Linus Torvalds1da177e2005-04-16 15:20:36 -07003440 hci_conn_hold(conn->hcon);
3441
Linus Torvalds1da177e2005-04-16 15:20:36 -07003442 bacpy(&bt_sk(sk)->src, conn->src);
3443 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003444 chan->psm = psm;
3445 chan->dcid = scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003446
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003447 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003448
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003449 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003450
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003451 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003452
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003453 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003454
Marcel Holtmann984947d2009-02-06 23:35:19 +01003455 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003456 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003457 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003458 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003459 result = L2CAP_CR_PEND;
3460 status = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08003461 chan->ops->defer(chan);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003462 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003463 __l2cap_state_change(chan, BT_CONFIG);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003464 result = L2CAP_CR_SUCCESS;
3465 status = L2CAP_CS_NO_INFO;
3466 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003467 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003468 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003469 result = L2CAP_CR_PEND;
3470 status = L2CAP_CS_AUTHEN_PEND;
3471 }
3472 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003473 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003474 result = L2CAP_CR_PEND;
3475 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003476 }
3477
Linus Torvalds1da177e2005-04-16 15:20:36 -07003478response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003479 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003480 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003481
3482sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003483 rsp.scid = cpu_to_le16(scid);
3484 rsp.dcid = cpu_to_le16(dcid);
3485 rsp.result = cpu_to_le16(result);
3486 rsp.status = cpu_to_le16(status);
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003487 l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003488
3489 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3490 struct l2cap_info_req info;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003491 info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003492
3493 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3494 conn->info_ident = l2cap_get_ident(conn);
3495
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003496 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003497
Gustavo Padovan2d792812012-10-06 10:07:01 +01003498 l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
3499 sizeof(info), &info);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003500 }
3501
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003502 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo Padovan2d792812012-10-06 10:07:01 +01003503 result == L2CAP_CR_SUCCESS) {
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003504 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003505 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003506 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003507 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003508 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003509 }
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003510}
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003511
Mat Martineau4c89b6a2012-10-11 17:48:22 +03003512static int l2cap_connect_req(struct l2cap_conn *conn,
3513 struct l2cap_cmd_hdr *cmd, u8 *data)
3514{
Gustavo Padovan300229f2012-10-12 19:40:40 +08003515 l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003516 return 0;
3517}
3518
Gustavo Padovan2d792812012-10-06 10:07:01 +01003519static inline int l2cap_connect_rsp(struct l2cap_conn *conn,
3520 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003521{
3522 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3523 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003524 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003525 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003526 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003527
3528 scid = __le16_to_cpu(rsp->scid);
3529 dcid = __le16_to_cpu(rsp->dcid);
3530 result = __le16_to_cpu(rsp->result);
3531 status = __le16_to_cpu(rsp->status);
3532
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003533 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x",
Gustavo Padovan2d792812012-10-06 10:07:01 +01003534 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003535
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003536 mutex_lock(&conn->chan_lock);
3537
Linus Torvalds1da177e2005-04-16 15:20:36 -07003538 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003539 chan = __l2cap_get_chan_by_scid(conn, scid);
3540 if (!chan) {
3541 err = -EFAULT;
3542 goto unlock;
3543 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003544 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003545 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3546 if (!chan) {
3547 err = -EFAULT;
3548 goto unlock;
3549 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003550 }
3551
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003552 err = 0;
3553
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003554 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003555
Linus Torvalds1da177e2005-04-16 15:20:36 -07003556 switch (result) {
3557 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03003558 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003559 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003560 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003561 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003562
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003563 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003564 break;
3565
Linus Torvalds1da177e2005-04-16 15:20:36 -07003566 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003567 l2cap_build_conf_req(chan, req), req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003568 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003569 break;
3570
3571 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003572 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003573 break;
3574
3575 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003576 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003577 break;
3578 }
3579
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003580 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003581
3582unlock:
3583 mutex_unlock(&conn->chan_lock);
3584
3585 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003586}
3587
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003588static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003589{
3590 /* FCS is enabled only in ERTM or streaming mode, if one or both
3591 * sides request it.
3592 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003593 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003594 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003595 else if (!test_bit(CONF_NO_FCS_RECV, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003596 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003597}
3598
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003599static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
3600 u8 ident, u16 flags)
3601{
3602 struct l2cap_conn *conn = chan->conn;
3603
3604 BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
3605 flags);
3606
3607 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3608 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3609
3610 l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
3611 l2cap_build_conf_rsp(chan, data,
3612 L2CAP_CONF_SUCCESS, flags), data);
3613}
3614
Gustavo Padovan2d792812012-10-06 10:07:01 +01003615static inline int l2cap_config_req(struct l2cap_conn *conn,
3616 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3617 u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003618{
3619 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3620 u16 dcid, flags;
3621 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003622 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003623 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003624
3625 dcid = __le16_to_cpu(req->dcid);
3626 flags = __le16_to_cpu(req->flags);
3627
3628 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3629
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003630 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003631 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003632 return -ENOENT;
3633
David S. Miller033b1142011-07-21 13:38:42 -07003634 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003635 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003636
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003637 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID);
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003638 rej.scid = cpu_to_le16(chan->scid);
3639 rej.dcid = cpu_to_le16(chan->dcid);
3640
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003641 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003642 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003643 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003644 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003645
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003646 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003647 len = cmd_len - sizeof(*req);
Dan Rosenberg7ac28812011-06-24 08:38:05 -04003648 if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003649 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003650 l2cap_build_conf_rsp(chan, rsp,
3651 L2CAP_CONF_REJECT, flags), rsp);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003652 goto unlock;
3653 }
3654
3655 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003656 memcpy(chan->conf_req + chan->conf_len, req->data, len);
3657 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003658
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003659 if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003660 /* Incomplete config. Send empty response. */
3661 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003662 l2cap_build_conf_rsp(chan, rsp,
3663 L2CAP_CONF_SUCCESS, flags), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003664 goto unlock;
3665 }
3666
3667 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003668 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003669 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003670 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003671 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003672 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003673
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003674 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003675 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003676
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003677 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003678 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003679
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003680 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02003681 goto unlock;
3682
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003683 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003684 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003685
Mat Martineau105bdf92012-04-27 16:50:48 -07003686 if (chan->mode == L2CAP_MODE_ERTM ||
3687 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003688 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003689
Mat Martineau3c588192012-04-11 10:48:42 -07003690 if (err < 0)
3691 l2cap_send_disconn_req(chan->conn, chan, -err);
3692 else
3693 l2cap_chan_ready(chan);
3694
Marcel Holtmann876d9482007-10-20 13:35:42 +02003695 goto unlock;
3696 }
3697
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003698 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003699 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003700 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003701 l2cap_build_conf_req(chan, buf), buf);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003702 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003703 }
3704
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003705 /* Got Conf Rsp PENDING from remote side and asume we sent
3706 Conf Rsp PENDING in the code above */
3707 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
Andrei Emeltchenko29d8a592012-09-21 12:30:05 +03003708 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003709
3710 /* check compatibility */
3711
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03003712 /* Send rsp for BR/EDR channel */
3713 if (!chan->ctrl_id)
3714 l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
3715 else
3716 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003717 }
3718
Linus Torvalds1da177e2005-04-16 15:20:36 -07003719unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003720 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003721 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003722}
3723
Gustavo Padovan2d792812012-10-06 10:07:01 +01003724static inline int l2cap_config_rsp(struct l2cap_conn *conn,
3725 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003726{
3727 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3728 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003729 struct l2cap_chan *chan;
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003730 int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07003731 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003732
3733 scid = __le16_to_cpu(rsp->scid);
3734 flags = __le16_to_cpu(rsp->flags);
3735 result = __le16_to_cpu(rsp->result);
3736
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003737 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
3738 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003739
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003740 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003741 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003742 return 0;
3743
3744 switch (result) {
3745 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003746 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003747 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003748 break;
3749
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003750 case L2CAP_CONF_PENDING:
3751 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
3752
3753 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3754 char buf[64];
3755
3756 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003757 buf, &result);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003758 if (len < 0) {
3759 l2cap_send_disconn_req(conn, chan, ECONNRESET);
3760 goto done;
3761 }
3762
3763 /* check compatibility */
3764
Andrei Emeltchenko79de8862012-10-15 11:58:42 +03003765 if (!chan->ctrl_id)
3766 l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
3767 0);
3768 else
3769 chan->ident = cmd->ident;
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003770 }
3771 goto done;
3772
Linus Torvalds1da177e2005-04-16 15:20:36 -07003773 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003774 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003775 char req[64];
3776
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003777 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003778 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003779 goto done;
3780 }
3781
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003782 /* throw out any old stored conf requests */
3783 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003784 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
Gustavo Padovan2d792812012-10-06 10:07:01 +01003785 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003786 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003787 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003788 goto done;
3789 }
3790
3791 l2cap_send_cmd(conn, l2cap_get_ident(conn),
Gustavo Padovan2d792812012-10-06 10:07:01 +01003792 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003793 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003794 if (result != L2CAP_CONF_SUCCESS)
3795 goto done;
3796 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003797 }
3798
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003799 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003800 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02003801
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003802 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003803 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003804 goto done;
3805 }
3806
Andrei Emeltchenko59e54bd2012-05-23 15:44:06 +03003807 if (flags & L2CAP_CONF_FLAG_CONTINUATION)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003808 goto done;
3809
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003810 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003811
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003812 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003813 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003814
Mat Martineau105bdf92012-04-27 16:50:48 -07003815 if (chan->mode == L2CAP_MODE_ERTM ||
3816 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003817 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003818
Mat Martineau3c588192012-04-11 10:48:42 -07003819 if (err < 0)
3820 l2cap_send_disconn_req(chan->conn, chan, -err);
3821 else
3822 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003823 }
3824
3825done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003826 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003827 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003828}
3829
Gustavo Padovan2d792812012-10-06 10:07:01 +01003830static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
3831 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003832{
3833 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3834 struct l2cap_disconn_rsp rsp;
3835 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003836 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003837 struct sock *sk;
3838
3839 scid = __le16_to_cpu(req->scid);
3840 dcid = __le16_to_cpu(req->dcid);
3841
3842 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3843
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003844 mutex_lock(&conn->chan_lock);
3845
3846 chan = __l2cap_get_chan_by_scid(conn, dcid);
3847 if (!chan) {
3848 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003849 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003850 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003851
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003852 l2cap_chan_lock(chan);
3853
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003854 sk = chan->sk;
3855
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003856 rsp.dcid = cpu_to_le16(chan->scid);
3857 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003858 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3859
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003860 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003861 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003862 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003863
Mat Martineau61d6ef32012-04-27 16:50:50 -07003864 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003865 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003866
3867 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003868
Gustavo Padovan80b98022012-05-27 22:27:51 -03003869 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003870 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003871
3872 mutex_unlock(&conn->chan_lock);
3873
Linus Torvalds1da177e2005-04-16 15:20:36 -07003874 return 0;
3875}
3876
Gustavo Padovan2d792812012-10-06 10:07:01 +01003877static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
3878 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003879{
3880 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3881 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003882 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003883
3884 scid = __le16_to_cpu(rsp->scid);
3885 dcid = __le16_to_cpu(rsp->dcid);
3886
3887 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3888
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003889 mutex_lock(&conn->chan_lock);
3890
3891 chan = __l2cap_get_chan_by_scid(conn, scid);
3892 if (!chan) {
3893 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003894 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003895 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003896
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003897 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003898
Mat Martineau61d6ef32012-04-27 16:50:50 -07003899 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003900 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003901
3902 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003903
Gustavo Padovan80b98022012-05-27 22:27:51 -03003904 chan->ops->close(chan);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003905 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003906
3907 mutex_unlock(&conn->chan_lock);
3908
Linus Torvalds1da177e2005-04-16 15:20:36 -07003909 return 0;
3910}
3911
Gustavo Padovan2d792812012-10-06 10:07:01 +01003912static inline int l2cap_information_req(struct l2cap_conn *conn,
3913 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003914{
3915 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003916 u16 type;
3917
3918 type = __le16_to_cpu(req->type);
3919
3920 BT_DBG("type 0x%4.4x", type);
3921
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003922 if (type == L2CAP_IT_FEAT_MASK) {
3923 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003924 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003925 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003926 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK);
3927 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03003928 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003929 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
Gustavo Padovan2d792812012-10-06 10:07:01 +01003930 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003931 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003932 feat_mask |= L2CAP_FEAT_EXT_FLOW
Gustavo Padovan2d792812012-10-06 10:07:01 +01003933 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003934
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003935 put_unaligned_le32(feat_mask, rsp->data);
Gustavo Padovan2d792812012-10-06 10:07:01 +01003936 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
3937 buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003938 } else if (type == L2CAP_IT_FIXED_CHAN) {
3939 u8 buf[12];
3940 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07003941
3942 if (enable_hs)
3943 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
3944 else
3945 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
3946
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003947 rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3948 rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03003949 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Gustavo Padovan2d792812012-10-06 10:07:01 +01003950 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
3951 buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003952 } else {
3953 struct l2cap_info_rsp rsp;
3954 rsp.type = cpu_to_le16(type);
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003955 rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP);
Gustavo Padovan2d792812012-10-06 10:07:01 +01003956 l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
3957 &rsp);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003958 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003959
3960 return 0;
3961}
3962
Gustavo Padovan2d792812012-10-06 10:07:01 +01003963static inline int l2cap_information_rsp(struct l2cap_conn *conn,
3964 struct l2cap_cmd_hdr *cmd, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003965{
3966 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3967 u16 type, result;
3968
3969 type = __le16_to_cpu(rsp->type);
3970 result = __le16_to_cpu(rsp->result);
3971
3972 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3973
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02003974 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
3975 if (cmd->ident != conn->info_ident ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01003976 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02003977 return 0;
3978
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003979 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003980
Ville Tervoadb08ed2010-08-04 09:43:33 +03003981 if (result != L2CAP_IR_SUCCESS) {
3982 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3983 conn->info_ident = 0;
3984
3985 l2cap_conn_start(conn);
3986
3987 return 0;
3988 }
3989
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003990 switch (type) {
3991 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07003992 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003993
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003994 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003995 struct l2cap_info_req req;
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03003996 req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003997
3998 conn->info_ident = l2cap_get_ident(conn);
3999
4000 l2cap_send_cmd(conn, conn->info_ident,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004001 L2CAP_INFO_REQ, sizeof(req), &req);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004002 } else {
4003 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
4004 conn->info_ident = 0;
4005
4006 l2cap_conn_start(conn);
4007 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004008 break;
4009
4010 case L2CAP_IT_FIXED_CHAN:
4011 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004012 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004013 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004014
4015 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004016 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004017 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004018
Linus Torvalds1da177e2005-04-16 15:20:36 -07004019 return 0;
4020}
4021
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004022static inline int l2cap_create_channel_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004023 struct l2cap_cmd_hdr *cmd,
4024 u16 cmd_len, void *data)
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004025{
4026 struct l2cap_create_chan_req *req = data;
4027 struct l2cap_create_chan_rsp rsp;
4028 u16 psm, scid;
4029
4030 if (cmd_len != sizeof(*req))
4031 return -EPROTO;
4032
4033 if (!enable_hs)
4034 return -EINVAL;
4035
4036 psm = le16_to_cpu(req->psm);
4037 scid = le16_to_cpu(req->scid);
4038
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004039 BT_DBG("psm 0x%2.2x, scid 0x%4.4x, amp_id %d", psm, scid, req->amp_id);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004040
4041 /* Placeholder: Always reject */
4042 rsp.dcid = 0;
4043 rsp.scid = cpu_to_le16(scid);
Andrei Emeltchenko8ce0c492012-03-12 12:13:09 +02004044 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4045 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004046
4047 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4048 sizeof(rsp), &rsp);
4049
4050 return 0;
4051}
4052
Gustavo Padovan2d792812012-10-06 10:07:01 +01004053static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn,
4054 struct l2cap_cmd_hdr *cmd,
4055 void *data)
4056{
4057 BT_DBG("conn %p", conn);
4058
4059 return l2cap_connect_rsp(conn, cmd, data);
4060}
4061
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004062static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004063 u16 icid, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004064{
4065 struct l2cap_move_chan_rsp rsp;
4066
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004067 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004068
4069 rsp.icid = cpu_to_le16(icid);
4070 rsp.result = cpu_to_le16(result);
4071
4072 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_RSP, sizeof(rsp), &rsp);
4073}
4074
4075static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004076 struct l2cap_chan *chan,
4077 u16 icid, u16 result)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004078{
4079 struct l2cap_move_chan_cfm cfm;
4080 u8 ident;
4081
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004082 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004083
4084 ident = l2cap_get_ident(conn);
4085 if (chan)
4086 chan->ident = ident;
4087
4088 cfm.icid = cpu_to_le16(icid);
4089 cfm.result = cpu_to_le16(result);
4090
4091 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM, sizeof(cfm), &cfm);
4092}
4093
4094static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004095 u16 icid)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004096{
4097 struct l2cap_move_chan_cfm_rsp rsp;
4098
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004099 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004100
4101 rsp.icid = cpu_to_le16(icid);
4102 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4103}
4104
4105static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004106 struct l2cap_cmd_hdr *cmd,
4107 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004108{
4109 struct l2cap_move_chan_req *req = data;
4110 u16 icid = 0;
4111 u16 result = L2CAP_MR_NOT_ALLOWED;
4112
4113 if (cmd_len != sizeof(*req))
4114 return -EPROTO;
4115
4116 icid = le16_to_cpu(req->icid);
4117
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004118 BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004119
4120 if (!enable_hs)
4121 return -EINVAL;
4122
4123 /* Placeholder: Always refuse */
4124 l2cap_send_move_chan_rsp(conn, cmd->ident, icid, result);
4125
4126 return 0;
4127}
4128
4129static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004130 struct l2cap_cmd_hdr *cmd,
4131 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004132{
4133 struct l2cap_move_chan_rsp *rsp = data;
4134 u16 icid, result;
4135
4136 if (cmd_len != sizeof(*rsp))
4137 return -EPROTO;
4138
4139 icid = le16_to_cpu(rsp->icid);
4140 result = le16_to_cpu(rsp->result);
4141
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004142 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004143
4144 /* Placeholder: Always unconfirmed */
4145 l2cap_send_move_chan_cfm(conn, NULL, icid, L2CAP_MC_UNCONFIRMED);
4146
4147 return 0;
4148}
4149
4150static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004151 struct l2cap_cmd_hdr *cmd,
4152 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004153{
4154 struct l2cap_move_chan_cfm *cfm = data;
4155 u16 icid, result;
4156
4157 if (cmd_len != sizeof(*cfm))
4158 return -EPROTO;
4159
4160 icid = le16_to_cpu(cfm->icid);
4161 result = le16_to_cpu(cfm->result);
4162
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004163 BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004164
4165 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4166
4167 return 0;
4168}
4169
4170static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004171 struct l2cap_cmd_hdr *cmd,
4172 u16 cmd_len, void *data)
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004173{
4174 struct l2cap_move_chan_cfm_rsp *rsp = data;
4175 u16 icid;
4176
4177 if (cmd_len != sizeof(*rsp))
4178 return -EPROTO;
4179
4180 icid = le16_to_cpu(rsp->icid);
4181
Andrei Emeltchenkoad0ac6c2012-07-10 15:27:50 +03004182 BT_DBG("icid 0x%4.4x", icid);
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004183
4184 return 0;
4185}
4186
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004187static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004188 u16 to_multiplier)
Claudio Takahaside731152011-02-11 19:28:55 -02004189{
4190 u16 max_latency;
4191
4192 if (min > max || min < 6 || max > 3200)
4193 return -EINVAL;
4194
4195 if (to_multiplier < 10 || to_multiplier > 3200)
4196 return -EINVAL;
4197
4198 if (max >= to_multiplier * 8)
4199 return -EINVAL;
4200
4201 max_latency = (to_multiplier * 8 / max) - 1;
4202 if (latency > 499 || latency > max_latency)
4203 return -EINVAL;
4204
4205 return 0;
4206}
4207
4208static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004209 struct l2cap_cmd_hdr *cmd,
4210 u8 *data)
Claudio Takahaside731152011-02-11 19:28:55 -02004211{
4212 struct hci_conn *hcon = conn->hcon;
4213 struct l2cap_conn_param_update_req *req;
4214 struct l2cap_conn_param_update_rsp rsp;
4215 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004216 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02004217
4218 if (!(hcon->link_mode & HCI_LM_MASTER))
4219 return -EINVAL;
4220
4221 cmd_len = __le16_to_cpu(cmd->len);
4222 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
4223 return -EPROTO;
4224
4225 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004226 min = __le16_to_cpu(req->min);
4227 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02004228 latency = __le16_to_cpu(req->latency);
4229 to_multiplier = __le16_to_cpu(req->to_multiplier);
4230
4231 BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
Gustavo Padovan2d792812012-10-06 10:07:01 +01004232 min, max, latency, to_multiplier);
Claudio Takahaside731152011-02-11 19:28:55 -02004233
4234 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004235
4236 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
4237 if (err)
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004238 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004239 else
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004240 rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
Claudio Takahaside731152011-02-11 19:28:55 -02004241
4242 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004243 sizeof(rsp), &rsp);
Claudio Takahaside731152011-02-11 19:28:55 -02004244
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004245 if (!err)
4246 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
4247
Claudio Takahaside731152011-02-11 19:28:55 -02004248 return 0;
4249}
4250
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004251static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004252 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4253 u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004254{
4255 int err = 0;
4256
4257 switch (cmd->code) {
4258 case L2CAP_COMMAND_REJ:
4259 l2cap_command_rej(conn, cmd, data);
4260 break;
4261
4262 case L2CAP_CONN_REQ:
4263 err = l2cap_connect_req(conn, cmd, data);
4264 break;
4265
4266 case L2CAP_CONN_RSP:
Mat Martineauf5a25982012-10-11 17:48:21 +03004267 case L2CAP_CREATE_CHAN_RSP:
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004268 err = l2cap_connect_rsp(conn, cmd, data);
4269 break;
4270
4271 case L2CAP_CONF_REQ:
4272 err = l2cap_config_req(conn, cmd, cmd_len, data);
4273 break;
4274
4275 case L2CAP_CONF_RSP:
4276 err = l2cap_config_rsp(conn, cmd, data);
4277 break;
4278
4279 case L2CAP_DISCONN_REQ:
4280 err = l2cap_disconnect_req(conn, cmd, data);
4281 break;
4282
4283 case L2CAP_DISCONN_RSP:
4284 err = l2cap_disconnect_rsp(conn, cmd, data);
4285 break;
4286
4287 case L2CAP_ECHO_REQ:
4288 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
4289 break;
4290
4291 case L2CAP_ECHO_RSP:
4292 break;
4293
4294 case L2CAP_INFO_REQ:
4295 err = l2cap_information_req(conn, cmd, data);
4296 break;
4297
4298 case L2CAP_INFO_RSP:
4299 err = l2cap_information_rsp(conn, cmd, data);
4300 break;
4301
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004302 case L2CAP_CREATE_CHAN_REQ:
4303 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
4304 break;
4305
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004306 case L2CAP_MOVE_CHAN_REQ:
4307 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
4308 break;
4309
4310 case L2CAP_MOVE_CHAN_RSP:
4311 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
4312 break;
4313
4314 case L2CAP_MOVE_CHAN_CFM:
4315 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
4316 break;
4317
4318 case L2CAP_MOVE_CHAN_CFM_RSP:
4319 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
4320 break;
4321
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004322 default:
4323 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
4324 err = -EINVAL;
4325 break;
4326 }
4327
4328 return err;
4329}
4330
4331static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004332 struct l2cap_cmd_hdr *cmd, u8 *data)
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004333{
4334 switch (cmd->code) {
4335 case L2CAP_COMMAND_REJ:
4336 return 0;
4337
4338 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02004339 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004340
4341 case L2CAP_CONN_PARAM_UPDATE_RSP:
4342 return 0;
4343
4344 default:
4345 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
4346 return -EINVAL;
4347 }
4348}
4349
4350static inline void l2cap_sig_channel(struct l2cap_conn *conn,
Gustavo Padovan2d792812012-10-06 10:07:01 +01004351 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004352{
4353 u8 *data = skb->data;
4354 int len = skb->len;
4355 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004356 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004357
4358 l2cap_raw_recv(conn, skb);
4359
4360 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07004361 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004362 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
4363 data += L2CAP_CMD_HDR_SIZE;
4364 len -= L2CAP_CMD_HDR_SIZE;
4365
Al Viro88219a02007-07-29 00:17:25 -07004366 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004367
Gustavo Padovan2d792812012-10-06 10:07:01 +01004368 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
4369 cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004370
Al Viro88219a02007-07-29 00:17:25 -07004371 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004372 BT_DBG("corrupted command");
4373 break;
4374 }
4375
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004376 if (conn->hcon->type == LE_LINK)
4377 err = l2cap_le_sig_cmd(conn, &cmd, data);
4378 else
4379 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004380
4381 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004382 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03004383
4384 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004385
4386 /* FIXME: Map err to a valid reason */
Andrei Emeltchenkoac734982012-05-24 15:42:51 +03004387 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Gustavo Padovan2d792812012-10-06 10:07:01 +01004388 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
4389 sizeof(rej), &rej);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004390 }
4391
Al Viro88219a02007-07-29 00:17:25 -07004392 data += cmd_len;
4393 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004394 }
4395
4396 kfree_skb(skb);
4397}
4398
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004399static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004400{
4401 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03004402 int hdr_size;
4403
4404 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
4405 hdr_size = L2CAP_EXT_HDR_SIZE;
4406 else
4407 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004408
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004409 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004410 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004411 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
4412 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
4413
4414 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03004415 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004416 }
4417 return 0;
4418}
4419
Mat Martineau6ea00482012-05-17 20:53:52 -07004420static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004421{
Mat Martineaue31f7632012-05-17 20:53:41 -07004422 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004423
Mat Martineaue31f7632012-05-17 20:53:41 -07004424 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004425
Mat Martineaue31f7632012-05-17 20:53:41 -07004426 memset(&control, 0, sizeof(control));
4427 control.sframe = 1;
4428 control.final = 1;
4429 control.reqseq = chan->buffer_seq;
4430 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004431
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004432 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07004433 control.super = L2CAP_SUPER_RNR;
4434 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004435 }
4436
Mat Martineaue31f7632012-05-17 20:53:41 -07004437 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
4438 chan->unacked_frames > 0)
4439 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004440
Mat Martineaue31f7632012-05-17 20:53:41 -07004441 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03004442 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004443
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004444 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07004445 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
4446 /* F-bit wasn't sent in an s-frame or i-frame yet, so
4447 * send it now.
4448 */
4449 control.super = L2CAP_SUPER_RR;
4450 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004451 }
4452}
4453
Gustavo Padovan2d792812012-10-06 10:07:01 +01004454static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
4455 struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004456{
Mat Martineau84084a32011-07-22 14:54:00 -07004457 /* skb->len reflects data in skb as well as all fragments
4458 * skb->data_len reflects only data in fragments
4459 */
4460 if (!skb_has_frag_list(skb))
4461 skb_shinfo(skb)->frag_list = new_frag;
4462
4463 new_frag->next = NULL;
4464
4465 (*last_frag)->next = new_frag;
4466 *last_frag = new_frag;
4467
4468 skb->len += new_frag->len;
4469 skb->data_len += new_frag->len;
4470 skb->truesize += new_frag->truesize;
4471}
4472
Mat Martineau4b51dae92012-05-17 20:53:37 -07004473static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
4474 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07004475{
4476 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004477
Mat Martineau4b51dae92012-05-17 20:53:37 -07004478 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004479 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07004480 if (chan->sdu)
4481 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004482
Gustavo Padovan80b98022012-05-27 22:27:51 -03004483 err = chan->ops->recv(chan, skb);
Mat Martineau84084a32011-07-22 14:54:00 -07004484 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004485
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004486 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07004487 if (chan->sdu)
4488 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004489
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004490 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004491 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004492
Mat Martineau84084a32011-07-22 14:54:00 -07004493 if (chan->sdu_len > chan->imtu) {
4494 err = -EMSGSIZE;
4495 break;
4496 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004497
Mat Martineau84084a32011-07-22 14:54:00 -07004498 if (skb->len >= chan->sdu_len)
4499 break;
4500
4501 chan->sdu = skb;
4502 chan->sdu_last_frag = skb;
4503
4504 skb = NULL;
4505 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004506 break;
4507
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004508 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004509 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004510 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004511
Mat Martineau84084a32011-07-22 14:54:00 -07004512 append_skb_frag(chan->sdu, skb,
4513 &chan->sdu_last_frag);
4514 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004515
Mat Martineau84084a32011-07-22 14:54:00 -07004516 if (chan->sdu->len >= chan->sdu_len)
4517 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004518
Mat Martineau84084a32011-07-22 14:54:00 -07004519 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004520 break;
4521
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004522 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004523 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004524 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004525
Mat Martineau84084a32011-07-22 14:54:00 -07004526 append_skb_frag(chan->sdu, skb,
4527 &chan->sdu_last_frag);
4528 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004529
Mat Martineau84084a32011-07-22 14:54:00 -07004530 if (chan->sdu->len != chan->sdu_len)
4531 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004532
Gustavo Padovan80b98022012-05-27 22:27:51 -03004533 err = chan->ops->recv(chan, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004534
Mat Martineau84084a32011-07-22 14:54:00 -07004535 if (!err) {
4536 /* Reassembly complete */
4537 chan->sdu = NULL;
4538 chan->sdu_last_frag = NULL;
4539 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004540 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004541 break;
4542 }
4543
Mat Martineau84084a32011-07-22 14:54:00 -07004544 if (err) {
4545 kfree_skb(skb);
4546 kfree_skb(chan->sdu);
4547 chan->sdu = NULL;
4548 chan->sdu_last_frag = NULL;
4549 chan->sdu_len = 0;
4550 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004551
Mat Martineau84084a32011-07-22 14:54:00 -07004552 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004553}
4554
Mat Martineaue3281402011-07-07 09:39:02 -07004555void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132eb2010-06-21 19:39:50 -03004556{
Mat Martineau61aa4f52012-05-17 20:53:40 -07004557 u8 event;
4558
4559 if (chan->mode != L2CAP_MODE_ERTM)
4560 return;
4561
4562 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
Andrei Emeltchenko401bb1f2012-05-21 15:47:46 +03004563 l2cap_tx(chan, NULL, NULL, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004564}
4565
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004566static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
4567{
Mat Martineau63838722012-05-17 20:53:45 -07004568 int err = 0;
4569 /* Pass sequential frames to l2cap_reassemble_sdu()
4570 * until a gap is encountered.
4571 */
4572
4573 BT_DBG("chan %p", chan);
4574
4575 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4576 struct sk_buff *skb;
4577 BT_DBG("Searching for skb with txseq %d (queue len %d)",
4578 chan->buffer_seq, skb_queue_len(&chan->srej_q));
4579
4580 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
4581
4582 if (!skb)
4583 break;
4584
4585 skb_unlink(skb, &chan->srej_q);
4586 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
4587 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
4588 if (err)
4589 break;
4590 }
4591
4592 if (skb_queue_empty(&chan->srej_q)) {
4593 chan->rx_state = L2CAP_RX_STATE_RECV;
4594 l2cap_send_ack(chan);
4595 }
4596
4597 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004598}
4599
4600static void l2cap_handle_srej(struct l2cap_chan *chan,
4601 struct l2cap_ctrl *control)
4602{
Mat Martineauf80842a2012-05-17 20:53:46 -07004603 struct sk_buff *skb;
4604
4605 BT_DBG("chan %p, control %p", chan, control);
4606
4607 if (control->reqseq == chan->next_tx_seq) {
4608 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4609 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4610 return;
4611 }
4612
4613 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4614
4615 if (skb == NULL) {
4616 BT_DBG("Seq %d not available for retransmission",
4617 control->reqseq);
4618 return;
4619 }
4620
4621 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
4622 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4623 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4624 return;
4625 }
4626
4627 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4628
4629 if (control->poll) {
4630 l2cap_pass_to_tx(chan, control);
4631
4632 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4633 l2cap_retransmit(chan, control);
4634 l2cap_ertm_send(chan);
4635
4636 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4637 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4638 chan->srej_save_reqseq = control->reqseq;
4639 }
4640 } else {
4641 l2cap_pass_to_tx_fbit(chan, control);
4642
4643 if (control->final) {
4644 if (chan->srej_save_reqseq != control->reqseq ||
4645 !test_and_clear_bit(CONN_SREJ_ACT,
4646 &chan->conn_state))
4647 l2cap_retransmit(chan, control);
4648 } else {
4649 l2cap_retransmit(chan, control);
4650 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4651 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4652 chan->srej_save_reqseq = control->reqseq;
4653 }
4654 }
4655 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004656}
4657
4658static void l2cap_handle_rej(struct l2cap_chan *chan,
4659 struct l2cap_ctrl *control)
4660{
Mat Martineaufcd289d2012-05-17 20:53:47 -07004661 struct sk_buff *skb;
4662
4663 BT_DBG("chan %p, control %p", chan, control);
4664
4665 if (control->reqseq == chan->next_tx_seq) {
4666 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4667 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4668 return;
4669 }
4670
4671 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4672
4673 if (chan->max_tx && skb &&
4674 bt_cb(skb)->control.retries >= chan->max_tx) {
4675 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4676 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4677 return;
4678 }
4679
4680 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4681
4682 l2cap_pass_to_tx(chan, control);
4683
4684 if (control->final) {
4685 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
4686 l2cap_retransmit_all(chan, control);
4687 } else {
4688 l2cap_retransmit_all(chan, control);
4689 l2cap_ertm_send(chan);
4690 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
4691 set_bit(CONN_REJ_ACT, &chan->conn_state);
4692 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004693}
4694
Mat Martineau4b51dae92012-05-17 20:53:37 -07004695static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
4696{
4697 BT_DBG("chan %p, txseq %d", chan, txseq);
4698
4699 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
4700 chan->expected_tx_seq);
4701
4702 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
4703 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
Gustavo Padovan2d792812012-10-06 10:07:01 +01004704 chan->tx_win) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07004705 /* See notes below regarding "double poll" and
4706 * invalid packets.
4707 */
4708 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4709 BT_DBG("Invalid/Ignore - after SREJ");
4710 return L2CAP_TXSEQ_INVALID_IGNORE;
4711 } else {
4712 BT_DBG("Invalid - in window after SREJ sent");
4713 return L2CAP_TXSEQ_INVALID;
4714 }
4715 }
4716
4717 if (chan->srej_list.head == txseq) {
4718 BT_DBG("Expected SREJ");
4719 return L2CAP_TXSEQ_EXPECTED_SREJ;
4720 }
4721
4722 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
4723 BT_DBG("Duplicate SREJ - txseq already stored");
4724 return L2CAP_TXSEQ_DUPLICATE_SREJ;
4725 }
4726
4727 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
4728 BT_DBG("Unexpected SREJ - not requested");
4729 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
4730 }
4731 }
4732
4733 if (chan->expected_tx_seq == txseq) {
4734 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4735 chan->tx_win) {
4736 BT_DBG("Invalid - txseq outside tx window");
4737 return L2CAP_TXSEQ_INVALID;
4738 } else {
4739 BT_DBG("Expected");
4740 return L2CAP_TXSEQ_EXPECTED;
4741 }
4742 }
4743
4744 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
Gustavo Padovan2d792812012-10-06 10:07:01 +01004745 __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
Mat Martineau4b51dae92012-05-17 20:53:37 -07004746 BT_DBG("Duplicate - expected_tx_seq later than txseq");
4747 return L2CAP_TXSEQ_DUPLICATE;
4748 }
4749
4750 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
4751 /* A source of invalid packets is a "double poll" condition,
4752 * where delays cause us to send multiple poll packets. If
4753 * the remote stack receives and processes both polls,
4754 * sequence numbers can wrap around in such a way that a
4755 * resent frame has a sequence number that looks like new data
4756 * with a sequence gap. This would trigger an erroneous SREJ
4757 * request.
4758 *
4759 * Fortunately, this is impossible with a tx window that's
4760 * less than half of the maximum sequence number, which allows
4761 * invalid frames to be safely ignored.
4762 *
4763 * With tx window sizes greater than half of the tx window
4764 * maximum, the frame is invalid and cannot be ignored. This
4765 * causes a disconnect.
4766 */
4767
4768 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4769 BT_DBG("Invalid/Ignore - txseq outside tx window");
4770 return L2CAP_TXSEQ_INVALID_IGNORE;
4771 } else {
4772 BT_DBG("Invalid - txseq outside tx window");
4773 return L2CAP_TXSEQ_INVALID;
4774 }
4775 } else {
4776 BT_DBG("Unexpected - txseq indicates missing frames");
4777 return L2CAP_TXSEQ_UNEXPECTED;
4778 }
4779}
4780
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004781static int l2cap_rx_state_recv(struct l2cap_chan *chan,
4782 struct l2cap_ctrl *control,
4783 struct sk_buff *skb, u8 event)
4784{
4785 int err = 0;
4786 bool skb_in_use = 0;
4787
4788 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4789 event);
4790
4791 switch (event) {
4792 case L2CAP_EV_RECV_IFRAME:
4793 switch (l2cap_classify_txseq(chan, control->txseq)) {
4794 case L2CAP_TXSEQ_EXPECTED:
4795 l2cap_pass_to_tx(chan, control);
4796
4797 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4798 BT_DBG("Busy, discarding expected seq %d",
4799 control->txseq);
4800 break;
4801 }
4802
4803 chan->expected_tx_seq = __next_seq(chan,
4804 control->txseq);
4805
4806 chan->buffer_seq = chan->expected_tx_seq;
4807 skb_in_use = 1;
4808
4809 err = l2cap_reassemble_sdu(chan, skb, control);
4810 if (err)
4811 break;
4812
4813 if (control->final) {
4814 if (!test_and_clear_bit(CONN_REJ_ACT,
4815 &chan->conn_state)) {
4816 control->final = 0;
4817 l2cap_retransmit_all(chan, control);
4818 l2cap_ertm_send(chan);
4819 }
4820 }
4821
4822 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
4823 l2cap_send_ack(chan);
4824 break;
4825 case L2CAP_TXSEQ_UNEXPECTED:
4826 l2cap_pass_to_tx(chan, control);
4827
4828 /* Can't issue SREJ frames in the local busy state.
4829 * Drop this frame, it will be seen as missing
4830 * when local busy is exited.
4831 */
4832 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4833 BT_DBG("Busy, discarding unexpected seq %d",
4834 control->txseq);
4835 break;
4836 }
4837
4838 /* There was a gap in the sequence, so an SREJ
4839 * must be sent for each missing frame. The
4840 * current frame is stored for later use.
4841 */
4842 skb_queue_tail(&chan->srej_q, skb);
4843 skb_in_use = 1;
4844 BT_DBG("Queued %p (queue len %d)", skb,
4845 skb_queue_len(&chan->srej_q));
4846
4847 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
4848 l2cap_seq_list_clear(&chan->srej_list);
4849 l2cap_send_srej(chan, control->txseq);
4850
4851 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
4852 break;
4853 case L2CAP_TXSEQ_DUPLICATE:
4854 l2cap_pass_to_tx(chan, control);
4855 break;
4856 case L2CAP_TXSEQ_INVALID_IGNORE:
4857 break;
4858 case L2CAP_TXSEQ_INVALID:
4859 default:
4860 l2cap_send_disconn_req(chan->conn, chan,
4861 ECONNRESET);
4862 break;
4863 }
4864 break;
4865 case L2CAP_EV_RECV_RR:
4866 l2cap_pass_to_tx(chan, control);
4867 if (control->final) {
4868 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4869
4870 if (!test_and_clear_bit(CONN_REJ_ACT,
4871 &chan->conn_state)) {
4872 control->final = 0;
4873 l2cap_retransmit_all(chan, control);
4874 }
4875
4876 l2cap_ertm_send(chan);
4877 } else if (control->poll) {
4878 l2cap_send_i_or_rr_or_rnr(chan);
4879 } else {
4880 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4881 &chan->conn_state) &&
4882 chan->unacked_frames)
4883 __set_retrans_timer(chan);
4884
4885 l2cap_ertm_send(chan);
4886 }
4887 break;
4888 case L2CAP_EV_RECV_RNR:
4889 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4890 l2cap_pass_to_tx(chan, control);
4891 if (control && control->poll) {
4892 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4893 l2cap_send_rr_or_rnr(chan, 0);
4894 }
4895 __clear_retrans_timer(chan);
4896 l2cap_seq_list_clear(&chan->retrans_list);
4897 break;
4898 case L2CAP_EV_RECV_REJ:
4899 l2cap_handle_rej(chan, control);
4900 break;
4901 case L2CAP_EV_RECV_SREJ:
4902 l2cap_handle_srej(chan, control);
4903 break;
4904 default:
4905 break;
4906 }
4907
4908 if (skb && !skb_in_use) {
4909 BT_DBG("Freeing %p", skb);
4910 kfree_skb(skb);
4911 }
4912
4913 return err;
4914}
4915
4916static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
4917 struct l2cap_ctrl *control,
4918 struct sk_buff *skb, u8 event)
4919{
4920 int err = 0;
4921 u16 txseq = control->txseq;
4922 bool skb_in_use = 0;
4923
4924 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4925 event);
4926
4927 switch (event) {
4928 case L2CAP_EV_RECV_IFRAME:
4929 switch (l2cap_classify_txseq(chan, txseq)) {
4930 case L2CAP_TXSEQ_EXPECTED:
4931 /* Keep frame for reassembly later */
4932 l2cap_pass_to_tx(chan, control);
4933 skb_queue_tail(&chan->srej_q, skb);
4934 skb_in_use = 1;
4935 BT_DBG("Queued %p (queue len %d)", skb,
4936 skb_queue_len(&chan->srej_q));
4937
4938 chan->expected_tx_seq = __next_seq(chan, txseq);
4939 break;
4940 case L2CAP_TXSEQ_EXPECTED_SREJ:
4941 l2cap_seq_list_pop(&chan->srej_list);
4942
4943 l2cap_pass_to_tx(chan, control);
4944 skb_queue_tail(&chan->srej_q, skb);
4945 skb_in_use = 1;
4946 BT_DBG("Queued %p (queue len %d)", skb,
4947 skb_queue_len(&chan->srej_q));
4948
4949 err = l2cap_rx_queued_iframes(chan);
4950 if (err)
4951 break;
4952
4953 break;
4954 case L2CAP_TXSEQ_UNEXPECTED:
4955 /* Got a frame that can't be reassembled yet.
4956 * Save it for later, and send SREJs to cover
4957 * the missing frames.
4958 */
4959 skb_queue_tail(&chan->srej_q, skb);
4960 skb_in_use = 1;
4961 BT_DBG("Queued %p (queue len %d)", skb,
4962 skb_queue_len(&chan->srej_q));
4963
4964 l2cap_pass_to_tx(chan, control);
4965 l2cap_send_srej(chan, control->txseq);
4966 break;
4967 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
4968 /* This frame was requested with an SREJ, but
4969 * some expected retransmitted frames are
4970 * missing. Request retransmission of missing
4971 * SREJ'd frames.
4972 */
4973 skb_queue_tail(&chan->srej_q, skb);
4974 skb_in_use = 1;
4975 BT_DBG("Queued %p (queue len %d)", skb,
4976 skb_queue_len(&chan->srej_q));
4977
4978 l2cap_pass_to_tx(chan, control);
4979 l2cap_send_srej_list(chan, control->txseq);
4980 break;
4981 case L2CAP_TXSEQ_DUPLICATE_SREJ:
4982 /* We've already queued this frame. Drop this copy. */
4983 l2cap_pass_to_tx(chan, control);
4984 break;
4985 case L2CAP_TXSEQ_DUPLICATE:
4986 /* Expecting a later sequence number, so this frame
4987 * was already received. Ignore it completely.
4988 */
4989 break;
4990 case L2CAP_TXSEQ_INVALID_IGNORE:
4991 break;
4992 case L2CAP_TXSEQ_INVALID:
4993 default:
4994 l2cap_send_disconn_req(chan->conn, chan,
4995 ECONNRESET);
4996 break;
4997 }
4998 break;
4999 case L2CAP_EV_RECV_RR:
5000 l2cap_pass_to_tx(chan, control);
5001 if (control->final) {
5002 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5003
5004 if (!test_and_clear_bit(CONN_REJ_ACT,
5005 &chan->conn_state)) {
5006 control->final = 0;
5007 l2cap_retransmit_all(chan, control);
5008 }
5009
5010 l2cap_ertm_send(chan);
5011 } else if (control->poll) {
5012 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5013 &chan->conn_state) &&
5014 chan->unacked_frames) {
5015 __set_retrans_timer(chan);
5016 }
5017
5018 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5019 l2cap_send_srej_tail(chan);
5020 } else {
5021 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5022 &chan->conn_state) &&
5023 chan->unacked_frames)
5024 __set_retrans_timer(chan);
5025
5026 l2cap_send_ack(chan);
5027 }
5028 break;
5029 case L2CAP_EV_RECV_RNR:
5030 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5031 l2cap_pass_to_tx(chan, control);
5032 if (control->poll) {
5033 l2cap_send_srej_tail(chan);
5034 } else {
5035 struct l2cap_ctrl rr_control;
5036 memset(&rr_control, 0, sizeof(rr_control));
5037 rr_control.sframe = 1;
5038 rr_control.super = L2CAP_SUPER_RR;
5039 rr_control.reqseq = chan->buffer_seq;
5040 l2cap_send_sframe(chan, &rr_control);
5041 }
5042
5043 break;
5044 case L2CAP_EV_RECV_REJ:
5045 l2cap_handle_rej(chan, control);
5046 break;
5047 case L2CAP_EV_RECV_SREJ:
5048 l2cap_handle_srej(chan, control);
5049 break;
5050 }
5051
5052 if (skb && !skb_in_use) {
5053 BT_DBG("Freeing %p", skb);
5054 kfree_skb(skb);
5055 }
5056
5057 return err;
5058}
5059
5060static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
5061{
5062 /* Make sure reqseq is for a packet that has been sent but not acked */
5063 u16 unacked;
5064
5065 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
5066 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
5067}
5068
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005069static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5070 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005071{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005072 int err = 0;
5073
5074 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
5075 control, skb, event, chan->rx_state);
5076
5077 if (__valid_reqseq(chan, control->reqseq)) {
5078 switch (chan->rx_state) {
5079 case L2CAP_RX_STATE_RECV:
5080 err = l2cap_rx_state_recv(chan, control, skb, event);
5081 break;
5082 case L2CAP_RX_STATE_SREJ_SENT:
5083 err = l2cap_rx_state_srej_sent(chan, control, skb,
5084 event);
5085 break;
5086 default:
5087 /* shut it down */
5088 break;
5089 }
5090 } else {
5091 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
5092 control->reqseq, chan->next_tx_seq,
5093 chan->expected_ack_seq);
5094 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
5095 }
5096
5097 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005098}
5099
5100static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5101 struct sk_buff *skb)
5102{
Mat Martineau4b51dae92012-05-17 20:53:37 -07005103 int err = 0;
5104
5105 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
5106 chan->rx_state);
5107
5108 if (l2cap_classify_txseq(chan, control->txseq) ==
5109 L2CAP_TXSEQ_EXPECTED) {
5110 l2cap_pass_to_tx(chan, control);
5111
5112 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
5113 __next_seq(chan, chan->buffer_seq));
5114
5115 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5116
5117 l2cap_reassemble_sdu(chan, skb, control);
5118 } else {
5119 if (chan->sdu) {
5120 kfree_skb(chan->sdu);
5121 chan->sdu = NULL;
5122 }
5123 chan->sdu_last_frag = NULL;
5124 chan->sdu_len = 0;
5125
5126 if (skb) {
5127 BT_DBG("Freeing %p", skb);
5128 kfree_skb(skb);
5129 }
5130 }
5131
5132 chan->last_acked_seq = control->txseq;
5133 chan->expected_tx_seq = __next_seq(chan, control->txseq);
5134
5135 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005136}
5137
5138static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
5139{
5140 struct l2cap_ctrl *control = &bt_cb(skb)->control;
5141 u16 len;
5142 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005143
Mat Martineaub76bbd62012-04-11 10:48:43 -07005144 __unpack_control(chan, skb);
5145
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005146 len = skb->len;
5147
5148 /*
5149 * We can just drop the corrupted I-frame here.
5150 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005151 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005152 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005153 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005154 goto drop;
5155
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005156 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005157 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005158
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005159 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005160 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005161
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005162 if (len > chan->mps) {
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005163 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005164 goto drop;
5165 }
5166
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005167 if (!control->sframe) {
5168 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005169
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005170 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
5171 control->sar, control->reqseq, control->final,
5172 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03005173
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005174 /* Validate F-bit - F=0 always valid, F=1 only
5175 * valid in TX WAIT_F
5176 */
5177 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005178 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005179
5180 if (chan->mode != L2CAP_MODE_STREAMING) {
5181 event = L2CAP_EV_RECV_IFRAME;
5182 err = l2cap_rx(chan, control, skb, event);
5183 } else {
5184 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005185 }
5186
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005187 if (err)
5188 l2cap_send_disconn_req(chan->conn, chan,
5189 ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005190 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005191 const u8 rx_func_to_event[4] = {
5192 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
5193 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
5194 };
5195
5196 /* Only I-frames are expected in streaming mode */
5197 if (chan->mode == L2CAP_MODE_STREAMING)
5198 goto drop;
5199
5200 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
5201 control->reqseq, control->final, control->poll,
5202 control->super);
5203
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005204 if (len != 0) {
5205 BT_ERR("%d", len);
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005206 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005207 goto drop;
5208 }
5209
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005210 /* Validate F and P bits */
5211 if (control->final && (control->poll ||
5212 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
5213 goto drop;
5214
5215 event = rx_func_to_event[control->super];
5216 if (l2cap_rx(chan, control, skb, event))
5217 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005218 }
5219
5220 return 0;
5221
5222drop:
5223 kfree_skb(skb);
5224 return 0;
5225}
5226
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005227static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
5228 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005229{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005230 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005231
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03005232 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005233 if (!chan) {
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005234 if (cid == L2CAP_CID_A2MP) {
5235 chan = a2mp_channel_create(conn, skb);
5236 if (!chan) {
5237 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005238 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005239 }
5240
5241 l2cap_chan_lock(chan);
5242 } else {
5243 BT_DBG("unknown cid 0x%4.4x", cid);
5244 /* Drop packet and return */
5245 kfree_skb(skb);
Andrei Emeltchenko13ca56e2012-05-31 11:18:55 +03005246 return;
Andrei Emeltchenko97e8e892012-05-29 13:59:17 +03005247 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005248 }
5249
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03005250 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005251
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005252 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005253 goto drop;
5254
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005255 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005256 case L2CAP_MODE_BASIC:
5257 /* If socket recv buffers overflows we drop data here
5258 * which is *bad* because L2CAP has to be reliable.
5259 * But we don't have any other choice. L2CAP doesn't
5260 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005261
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005262 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005263 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005264
Gustavo Padovan80b98022012-05-27 22:27:51 -03005265 if (!chan->ops->recv(chan, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005266 goto done;
5267 break;
5268
5269 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005270 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005271 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005272 goto done;
5273
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005274 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005275 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005276 break;
5277 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005278
5279drop:
5280 kfree_skb(skb);
5281
5282done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005283 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005284}
5285
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03005286static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
5287 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005288{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005289 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005290
Ido Yarivc2287682012-04-20 15:46:07 -03005291 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005292 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005293 goto drop;
5294
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005295 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005296
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005297 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005298 goto drop;
5299
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005300 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005301 goto drop;
5302
Gustavo Padovan80b98022012-05-27 22:27:51 -03005303 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko84104b22012-05-31 11:18:56 +03005304 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005305
5306drop:
5307 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005308}
5309
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03005310static void l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
5311 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005312{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005313 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005314
Ido Yarivc2287682012-04-20 15:46:07 -03005315 chan = l2cap_global_chan_by_scid(0, cid, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005316 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005317 goto drop;
5318
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005319 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005320
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005321 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005322 goto drop;
5323
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005324 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005325 goto drop;
5326
Gustavo Padovan80b98022012-05-27 22:27:51 -03005327 if (!chan->ops->recv(chan, skb))
Andrei Emeltchenko6810fca2012-05-31 11:18:57 +03005328 return;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005329
5330drop:
5331 kfree_skb(skb);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005332}
5333
Linus Torvalds1da177e2005-04-16 15:20:36 -07005334static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
5335{
5336 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07005337 u16 cid, len;
5338 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005339
5340 skb_pull(skb, L2CAP_HDR_SIZE);
5341 cid = __le16_to_cpu(lh->cid);
5342 len = __le16_to_cpu(lh->len);
5343
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005344 if (len != skb->len) {
5345 kfree_skb(skb);
5346 return;
5347 }
5348
Linus Torvalds1da177e2005-04-16 15:20:36 -07005349 BT_DBG("len %d, cid 0x%4.4x", len, cid);
5350
5351 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005352 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005353 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005354 l2cap_sig_channel(conn, skb);
5355 break;
5356
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005357 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02005358 psm = get_unaligned((__le16 *) skb->data);
Andrei Emeltchenko0181a702012-05-29 10:04:05 +03005359 skb_pull(skb, L2CAP_PSMLEN_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005360 l2cap_conless_channel(conn, psm, skb);
5361 break;
5362
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005363 case L2CAP_CID_LE_DATA:
5364 l2cap_att_channel(conn, cid, skb);
5365 break;
5366
Anderson Brigliab501d6a2011-06-07 18:46:31 -03005367 case L2CAP_CID_SMP:
5368 if (smp_sig_channel(conn, skb))
5369 l2cap_conn_del(conn->hcon, EACCES);
5370 break;
5371
Linus Torvalds1da177e2005-04-16 15:20:36 -07005372 default:
5373 l2cap_data_channel(conn, cid, skb);
5374 break;
5375 }
5376}
5377
5378/* ---- L2CAP interface with lower layer (HCI) ---- */
5379
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005380int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005381{
5382 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005383 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005384
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03005385 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005386
5387 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005388 read_lock(&chan_list_lock);
5389 list_for_each_entry(c, &chan_list, global_l) {
5390 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005391
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005392 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005393 continue;
5394
5395 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005396 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005397 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005398 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005399 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005400 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
5401 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005402 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005403 lm2 |= HCI_LM_MASTER;
5404 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005405 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005406 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005407
5408 return exact ? lm1 : lm2;
5409}
5410
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03005411void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005412{
Marcel Holtmann01394182006-07-03 10:02:46 +02005413 struct l2cap_conn *conn;
5414
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03005415 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005416
Linus Torvalds1da177e2005-04-16 15:20:36 -07005417 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005418 conn = l2cap_conn_add(hcon, status);
5419 if (conn)
5420 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02005421 } else
Joe Perchese1750722011-06-29 18:18:29 -07005422 l2cap_conn_del(hcon, bt_to_errno(status));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005423
Linus Torvalds1da177e2005-04-16 15:20:36 -07005424}
5425
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005426int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01005427{
5428 struct l2cap_conn *conn = hcon->l2cap_data;
5429
5430 BT_DBG("hcon %p", hcon);
5431
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005432 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02005433 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01005434 return conn->disc_reason;
5435}
5436
Andrei Emeltchenko9e664632012-07-24 16:06:15 +03005437void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005438{
5439 BT_DBG("hcon %p reason %d", hcon, reason);
5440
Joe Perchese1750722011-06-29 18:18:29 -07005441 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005442}
5443
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005444static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005445{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03005446 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01005447 return;
5448
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005449 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005450 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005451 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005452 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03005453 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005454 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005455 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03005456 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005457 }
5458}
5459
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005460int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005461{
Marcel Holtmann40be4922008-07-14 20:13:50 +02005462 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005463 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005464
Marcel Holtmann01394182006-07-03 10:02:46 +02005465 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005466 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02005467
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03005468 BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005469
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005470 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05305471 if (!status && encrypt)
5472 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02005473 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005474 }
5475
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005476 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005477
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005478 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005479 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005480
Andrei Emeltchenko89d8b402012-07-10 15:27:51 +03005481 BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
5482 state_to_string(chan->state));
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005483
Andrei Emeltchenko78eb2f92012-07-19 17:03:47 +03005484 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) {
5485 l2cap_chan_unlock(chan);
5486 continue;
5487 }
5488
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005489 if (chan->scid == L2CAP_CID_LE_DATA) {
5490 if (!status && encrypt) {
5491 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02005492 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005493 }
5494
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005495 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005496 continue;
5497 }
5498
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03005499 if (test_bit(CONF_CONNECT_PEND, &chan->conf_state)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005500 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01005501 continue;
5502 }
5503
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005504 if (!status && (chan->state == BT_CONNECTED ||
Gustavo Padovan2d792812012-10-06 10:07:01 +01005505 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03005506 struct sock *sk = chan->sk;
5507
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005508 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03005509 sk->sk_state_change(sk);
5510
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005511 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005512 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02005513 continue;
5514 }
5515
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005516 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005517 if (!status) {
Andrei Emeltchenko93c3e8f2012-09-27 17:26:16 +03005518 l2cap_start_connection(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005519 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005520 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005521 }
Gustavo F. Padovan89bc500e2011-06-03 00:19:47 -03005522 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005523 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005524 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005525 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005526
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005527 lock_sock(sk);
5528
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005529 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005530 if (test_bit(BT_SK_DEFER_SETUP,
5531 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005532 res = L2CAP_CR_PEND;
5533 stat = L2CAP_CS_AUTHOR_PEND;
Gustavo Padovan2dc4e512012-10-12 19:35:24 +08005534 chan->ops->defer(chan);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005535 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005536 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005537 res = L2CAP_CR_SUCCESS;
5538 stat = L2CAP_CS_NO_INFO;
5539 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005540 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005541 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005542 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005543 res = L2CAP_CR_SEC_BLOCK;
5544 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005545 }
5546
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005547 release_sock(sk);
5548
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03005549 rsp.scid = cpu_to_le16(chan->dcid);
5550 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005551 rsp.result = cpu_to_le16(res);
5552 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03005553 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
Gustavo Padovan2d792812012-10-06 10:07:01 +01005554 sizeof(rsp), &rsp);
Mat Martineau2d369352012-05-23 14:59:30 -07005555
5556 if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
5557 res == L2CAP_CR_SUCCESS) {
5558 char buf[128];
5559 set_bit(CONF_REQ_SENT, &chan->conf_state);
5560 l2cap_send_cmd(conn, l2cap_get_ident(conn),
5561 L2CAP_CONF_REQ,
5562 l2cap_build_conf_req(chan, buf),
5563 buf);
5564 chan->num_conf_req++;
5565 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005566 }
5567
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005568 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005569 }
5570
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005571 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005572
Linus Torvalds1da177e2005-04-16 15:20:36 -07005573 return 0;
5574}
5575
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005576int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005577{
5578 struct l2cap_conn *conn = hcon->l2cap_data;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03005579 struct l2cap_hdr *hdr;
5580 int len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005581
Andrei Emeltchenko1d13a252012-10-15 11:58:41 +03005582 /* For AMP controller do not create l2cap conn */
5583 if (!conn && hcon->hdev->dev_type != HCI_BREDR)
5584 goto drop;
5585
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02005586 if (!conn)
5587 conn = l2cap_conn_add(hcon, 0);
5588
5589 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005590 goto drop;
5591
5592 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
5593
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03005594 switch (flags) {
5595 case ACL_START:
5596 case ACL_START_NO_FLUSH:
5597 case ACL_COMPLETE:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005598 if (conn->rx_len) {
5599 BT_ERR("Unexpected start frame (len %d)", skb->len);
5600 kfree_skb(conn->rx_skb);
5601 conn->rx_skb = NULL;
5602 conn->rx_len = 0;
5603 l2cap_conn_unreliable(conn, ECOMM);
5604 }
5605
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03005606 /* Start fragment always begin with Basic L2CAP header */
5607 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005608 BT_ERR("Frame is too short (len %d)", skb->len);
5609 l2cap_conn_unreliable(conn, ECOMM);
5610 goto drop;
5611 }
5612
5613 hdr = (struct l2cap_hdr *) skb->data;
5614 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
5615
5616 if (len == skb->len) {
5617 /* Complete frame received */
5618 l2cap_recv_frame(conn, skb);
5619 return 0;
5620 }
5621
5622 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
5623
5624 if (skb->len > len) {
5625 BT_ERR("Frame is too long (len %d, expected len %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01005626 skb->len, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005627 l2cap_conn_unreliable(conn, ECOMM);
5628 goto drop;
5629 }
5630
5631 /* Allocate skb for the complete frame (with header) */
Gustavo Padovan8bcde1f2012-05-28 19:18:14 -03005632 conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03005633 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005634 goto drop;
5635
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005636 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01005637 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005638 conn->rx_len = len - skb->len;
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03005639 break;
5640
5641 case ACL_CONT:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005642 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
5643
5644 if (!conn->rx_len) {
5645 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
5646 l2cap_conn_unreliable(conn, ECOMM);
5647 goto drop;
5648 }
5649
5650 if (skb->len > conn->rx_len) {
5651 BT_ERR("Fragment is too long (len %d, expected %d)",
Gustavo Padovan2d792812012-10-06 10:07:01 +01005652 skb->len, conn->rx_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005653 kfree_skb(conn->rx_skb);
5654 conn->rx_skb = NULL;
5655 conn->rx_len = 0;
5656 l2cap_conn_unreliable(conn, ECOMM);
5657 goto drop;
5658 }
5659
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005660 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Gustavo Padovan2d792812012-10-06 10:07:01 +01005661 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005662 conn->rx_len -= skb->len;
5663
5664 if (!conn->rx_len) {
5665 /* Complete frame received */
5666 l2cap_recv_frame(conn, conn->rx_skb);
5667 conn->rx_skb = NULL;
5668 }
Andrei Emeltchenkod73a0982012-10-15 11:58:40 +03005669 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005670 }
5671
5672drop:
5673 kfree_skb(skb);
5674 return 0;
5675}
5676
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005677static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005678{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005679 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005680
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005681 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005682
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005683 list_for_each_entry(c, &chan_list, global_l) {
5684 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005685
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +03005686 seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
5687 &bt_sk(sk)->src, &bt_sk(sk)->dst,
5688 c->state, __le16_to_cpu(c->psm),
5689 c->scid, c->dcid, c->imtu, c->omtu,
5690 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02005691 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005692
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005693 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005694
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005695 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005696}
5697
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005698static int l2cap_debugfs_open(struct inode *inode, struct file *file)
5699{
5700 return single_open(file, l2cap_debugfs_show, inode->i_private);
5701}
5702
5703static const struct file_operations l2cap_debugfs_fops = {
5704 .open = l2cap_debugfs_open,
5705 .read = seq_read,
5706 .llseek = seq_lseek,
5707 .release = single_release,
5708};
5709
5710static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005711
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005712int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005713{
5714 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005715
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005716 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005717 if (err < 0)
5718 return err;
5719
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005720 if (bt_debugfs) {
Gustavo Padovan2d792812012-10-06 10:07:01 +01005721 l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
5722 NULL, &l2cap_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005723 if (!l2cap_debugfs)
5724 BT_ERR("Failed to create L2CAP debug file");
5725 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005726
Linus Torvalds1da177e2005-04-16 15:20:36 -07005727 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005728}
5729
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005730void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005731{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005732 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005733 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005734}
5735
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03005736module_param(disable_ertm, bool, 0644);
5737MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");