blob: 38e9a0ea4f486ab2f8c0c95ae16366076731fa99 [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
33#include <linux/types.h>
Randy Dunlap4fc268d2006-01-11 12:17:47 -080034#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035#include <linux/errno.h>
36#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070037#include <linux/sched.h>
38#include <linux/slab.h>
39#include <linux/poll.h>
40#include <linux/fcntl.h>
41#include <linux/init.h>
42#include <linux/interrupt.h>
43#include <linux/socket.h>
44#include <linux/skbuff.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070045#include <linux/list.h>
Marcel Holtmannbe9d1222005-11-08 09:57:38 -080046#include <linux/device.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010047#include <linux/debugfs.h>
48#include <linux/seq_file.h>
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -030049#include <linux/uaccess.h>
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -030050#include <linux/crc16.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070051#include <net/sock.h>
52
Linus Torvalds1da177e2005-04-16 15:20:36 -070053#include <asm/unaligned.h>
54
55#include <net/bluetooth/bluetooth.h>
56#include <net/bluetooth/hci_core.h>
57#include <net/bluetooth/l2cap.h>
Anderson Brigliab501d6a2011-06-07 18:46:31 -030058#include <net/bluetooth/smp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070059
Mat Martineaub191e032012-05-17 20:53:31 -070060bool disable_ertm = 1;
Marcel Holtmannf0709e02007-10-20 13:38:51 +020061
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -070062static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
Mat Martineau50a147c2011-11-02 16:18:34 -070063static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP, };
Linus Torvalds1da177e2005-04-16 15:20:36 -070064
Johannes Bergb5ad8b72011-06-01 08:54:45 +020065static LIST_HEAD(chan_list);
66static DEFINE_RWLOCK(chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070067
Linus Torvalds1da177e2005-04-16 15:20:36 -070068static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
69 u8 code, u8 ident, u16 dlen, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030070static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
71 void *data);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -030072static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -030073static void l2cap_send_disconn_req(struct l2cap_conn *conn,
Gustavo Padovanc5daa682012-05-16 12:17:10 -030074 struct l2cap_chan *chan, int err);
Linus Torvalds1da177e2005-04-16 15:20:36 -070075
Mat Martineau608bcc62012-05-17 20:53:32 -070076static int l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
77 struct sk_buff_head *skbs, u8 event);
78
Marcel Holtmann01394182006-07-03 10:02:46 +020079/* ---- L2CAP channels ---- */
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -030080
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030081static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020082{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020083 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030084
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020085 list_for_each_entry(c, &conn->chan_l, list) {
86 if (c->dcid == cid)
87 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020088 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020089 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +020090}
91
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030092static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +020093{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020094 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -030095
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +020096 list_for_each_entry(c, &conn->chan_l, list) {
97 if (c->scid == cid)
98 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +020099 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200100 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200101}
102
103/* Find channel with given SCID.
Mat Martineauef191ad2012-05-02 09:42:00 -0700104 * Returns locked channel. */
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300105static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid)
Marcel Holtmann01394182006-07-03 10:02:46 +0200106{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300107 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300108
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200109 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300110 c = __l2cap_get_chan_by_scid(conn, cid);
Mat Martineauef191ad2012-05-02 09:42:00 -0700111 if (c)
112 l2cap_chan_lock(c);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200113 mutex_unlock(&conn->chan_lock);
114
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300115 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200116}
117
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300118static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident)
Marcel Holtmann01394182006-07-03 10:02:46 +0200119{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200120 struct l2cap_chan *c;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300121
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200122 list_for_each_entry(c, &conn->chan_l, list) {
123 if (c->ident == ident)
124 return c;
Marcel Holtmann01394182006-07-03 10:02:46 +0200125 }
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200126 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200127}
128
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300129static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300130{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300131 struct l2cap_chan *c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300132
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300133 list_for_each_entry(c, &chan_list, global_l) {
134 if (c->sport == psm && !bacmp(&bt_sk(c->sk)->src, src))
Szymon Janc250938c2011-11-16 09:32:22 +0100135 return c;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300136 }
Szymon Janc250938c2011-11-16 09:32:22 +0100137 return NULL;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300138}
139
140int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
141{
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300142 int err;
143
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200144 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300145
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300146 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300147 err = -EADDRINUSE;
148 goto done;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300149 }
150
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300151 if (psm) {
152 chan->psm = psm;
153 chan->sport = psm;
154 err = 0;
155 } else {
156 u16 p;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300157
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300158 err = -EINVAL;
159 for (p = 0x1001; p < 0x1100; p += 2)
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300160 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300161 chan->psm = cpu_to_le16(p);
162 chan->sport = cpu_to_le16(p);
163 err = 0;
164 break;
165 }
166 }
167
168done:
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200169 write_unlock(&chan_list_lock);
Gustavo F. Padovan73b2ec12011-04-18 19:36:44 -0300170 return err;
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300171}
172
173int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
174{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200175 write_lock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300176
177 chan->scid = scid;
178
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200179 write_unlock(&chan_list_lock);
Gustavo F. Padovan9e4425f2011-04-18 18:38:43 -0300180
181 return 0;
182}
183
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300184static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
Marcel Holtmann01394182006-07-03 10:02:46 +0200185{
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300186 u16 cid = L2CAP_CID_DYN_START;
Marcel Holtmann01394182006-07-03 10:02:46 +0200187
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -0300188 for (; cid < L2CAP_CID_DYN_END; cid++) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300189 if (!__l2cap_get_chan_by_scid(conn, cid))
Marcel Holtmann01394182006-07-03 10:02:46 +0200190 return cid;
191 }
192
193 return 0;
194}
195
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200196static void __l2cap_state_change(struct l2cap_chan *chan, int state)
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300197{
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +0200198 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
Gustavo F. Padovanbadaaa02011-11-23 20:11:46 -0200199 state_to_string(state));
200
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300201 chan->state = state;
202 chan->ops->state_change(chan->data, state);
203}
204
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200205static void l2cap_state_change(struct l2cap_chan *chan, int state)
206{
207 struct sock *sk = chan->sk;
208
209 lock_sock(sk);
210 __l2cap_state_change(chan, state);
211 release_sock(sk);
212}
213
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200214static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err)
215{
216 struct sock *sk = chan->sk;
217
218 sk->sk_err = err;
219}
220
221static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
222{
223 struct sock *sk = chan->sk;
224
225 lock_sock(sk);
226 __l2cap_chan_set_err(chan, err);
227 release_sock(sk);
228}
229
Mat Martineau4239d162012-05-17 20:53:49 -0700230static void __set_retrans_timer(struct l2cap_chan *chan)
231{
232 if (!delayed_work_pending(&chan->monitor_timer) &&
233 chan->retrans_timeout) {
234 l2cap_set_timer(chan, &chan->retrans_timer,
235 msecs_to_jiffies(chan->retrans_timeout));
236 }
237}
238
239static void __set_monitor_timer(struct l2cap_chan *chan)
240{
241 __clear_retrans_timer(chan);
242 if (chan->monitor_timeout) {
243 l2cap_set_timer(chan, &chan->monitor_timer,
244 msecs_to_jiffies(chan->monitor_timeout));
245 }
246}
247
Mat Martineau608bcc62012-05-17 20:53:32 -0700248static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
249 u16 seq)
250{
251 struct sk_buff *skb;
252
253 skb_queue_walk(head, skb) {
254 if (bt_cb(skb)->control.txseq == seq)
255 return skb;
256 }
257
258 return NULL;
259}
260
Mat Martineau3c588192012-04-11 10:48:42 -0700261/* ---- L2CAP sequence number lists ---- */
262
263/* For ERTM, ordered lists of sequence numbers must be tracked for
264 * SREJ requests that are received and for frames that are to be
265 * retransmitted. These seq_list functions implement a singly-linked
266 * list in an array, where membership in the list can also be checked
267 * in constant time. Items can also be added to the tail of the list
268 * and removed from the head in constant time, without further memory
269 * allocs or frees.
270 */
271
272static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
273{
274 size_t alloc_size, i;
275
276 /* Allocated size is a power of 2 to map sequence numbers
277 * (which may be up to 14 bits) in to a smaller array that is
278 * sized for the negotiated ERTM transmit windows.
279 */
280 alloc_size = roundup_pow_of_two(size);
281
282 seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
283 if (!seq_list->list)
284 return -ENOMEM;
285
286 seq_list->mask = alloc_size - 1;
287 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
288 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
289 for (i = 0; i < alloc_size; i++)
290 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
291
292 return 0;
293}
294
295static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
296{
297 kfree(seq_list->list);
298}
299
300static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
301 u16 seq)
302{
303 /* Constant-time check for list membership */
304 return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
305}
306
307static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
308{
309 u16 mask = seq_list->mask;
310
311 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
312 /* In case someone tries to pop the head of an empty list */
313 return L2CAP_SEQ_LIST_CLEAR;
314 } else if (seq_list->head == seq) {
315 /* Head can be removed in constant time */
316 seq_list->head = seq_list->list[seq & mask];
317 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
318
319 if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
320 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
321 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
322 }
323 } else {
324 /* Walk the list to find the sequence number */
325 u16 prev = seq_list->head;
326 while (seq_list->list[prev & mask] != seq) {
327 prev = seq_list->list[prev & mask];
328 if (prev == L2CAP_SEQ_LIST_TAIL)
329 return L2CAP_SEQ_LIST_CLEAR;
330 }
331
332 /* Unlink the number from the list and clear it */
333 seq_list->list[prev & mask] = seq_list->list[seq & mask];
334 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
335 if (seq_list->tail == seq)
336 seq_list->tail = prev;
337 }
338 return seq;
339}
340
341static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
342{
343 /* Remove the head in constant time */
344 return l2cap_seq_list_remove(seq_list, seq_list->head);
345}
346
347static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
348{
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300349 u16 i;
Mat Martineau3c588192012-04-11 10:48:42 -0700350
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300351 if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
352 return;
353
354 for (i = 0; i <= seq_list->mask; i++)
355 seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
356
357 seq_list->head = L2CAP_SEQ_LIST_CLEAR;
358 seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
Mat Martineau3c588192012-04-11 10:48:42 -0700359}
360
361static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
362{
363 u16 mask = seq_list->mask;
364
365 /* All appends happen in constant time */
366
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300367 if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
368 return;
Mat Martineau3c588192012-04-11 10:48:42 -0700369
Gustavo Padovanf522ae32012-05-09 18:28:00 -0300370 if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
371 seq_list->head = seq;
372 else
373 seq_list->list[seq_list->tail & mask] = seq;
374
375 seq_list->tail = seq;
376 seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
Mat Martineau3c588192012-04-11 10:48:42 -0700377}
378
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300379static void l2cap_chan_timeout(struct work_struct *work)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300380{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300381 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
382 chan_timer.work);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200383 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300384 int reason;
385
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200386 BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300387
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200388 mutex_lock(&conn->chan_lock);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200389 l2cap_chan_lock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300390
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300391 if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300392 reason = ECONNREFUSED;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300393 else if (chan->state == BT_CONNECT &&
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300394 chan->sec_level != BT_SECURITY_SDP)
395 reason = ECONNREFUSED;
396 else
397 reason = ETIMEDOUT;
398
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300399 l2cap_chan_close(chan, reason);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300400
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200401 l2cap_chan_unlock(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300402
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -0300403 chan->ops->close(chan->data);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200404 mutex_unlock(&conn->chan_lock);
405
Ulisses Furquim371fd832011-12-21 20:02:36 -0200406 l2cap_chan_put(chan);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300407}
408
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300409struct l2cap_chan *l2cap_chan_create(void)
Marcel Holtmann01394182006-07-03 10:02:46 +0200410{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300411 struct l2cap_chan *chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200412
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300413 chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
414 if (!chan)
415 return NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200416
Andrei Emeltchenkoc03b3552012-02-21 12:54:56 +0200417 mutex_init(&chan->lock);
418
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200419 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300420 list_add(&chan->global_l, &chan_list);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200421 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300422
Gustavo F. Padovan721c4182011-06-23 19:29:58 -0300423 INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
Gustavo F. Padovanab078012011-05-02 18:25:01 -0300424
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300425 chan->state = BT_OPEN;
426
Gustavo F. Padovan71ba0e52011-05-17 14:34:52 -0300427 atomic_set(&chan->refcnt, 1);
428
Mat Martineau28270112012-05-17 21:14:09 -0700429 /* This flag is cleared in l2cap_chan_ready() */
430 set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
431
Gustavo Padovaneef1d9b2012-03-25 13:59:16 -0300432 BT_DBG("chan %p", chan);
Szymon Jancabc545b2011-11-03 16:05:44 +0100433
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300434 return chan;
Marcel Holtmann01394182006-07-03 10:02:46 +0200435}
436
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300437void l2cap_chan_destroy(struct l2cap_chan *chan)
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300438{
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200439 write_lock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300440 list_del(&chan->global_l);
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200441 write_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -0300442
Ulisses Furquim371fd832011-12-21 20:02:36 -0200443 l2cap_chan_put(chan);
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300444}
445
Andrei Emeltchenkobd4b1652012-03-28 16:31:25 +0300446void l2cap_chan_set_defaults(struct l2cap_chan *chan)
447{
448 chan->fcs = L2CAP_FCS_CRC16;
449 chan->max_tx = L2CAP_DEFAULT_MAX_TX;
450 chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
451 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
452 chan->sec_level = BT_SECURITY_LOW;
453
454 set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
455}
456
Andrei Emeltchenko14a28492012-03-23 16:31:49 +0200457static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Marcel Holtmann01394182006-07-03 10:02:46 +0200458{
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -0300459 BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
Andrei Emeltchenko097db762012-03-09 14:16:17 +0200460 __le16_to_cpu(chan->psm), chan->dcid);
Marcel Holtmann01394182006-07-03 10:02:46 +0200461
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200462 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +0100463
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300464 chan->conn = conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200465
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200466 switch (chan->chan_type) {
467 case L2CAP_CHAN_CONN_ORIENTED:
Ville Tervob62f3282011-02-10 22:38:50 -0300468 if (conn->hcon->type == LE_LINK) {
469 /* LE connection */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300470 chan->omtu = L2CAP_LE_DEFAULT_MTU;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300471 chan->scid = L2CAP_CID_LE_DATA;
472 chan->dcid = L2CAP_CID_LE_DATA;
Ville Tervob62f3282011-02-10 22:38:50 -0300473 } else {
474 /* Alloc CID for connection-oriented socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300475 chan->scid = l2cap_alloc_cid(conn);
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300476 chan->omtu = L2CAP_DEFAULT_MTU;
Ville Tervob62f3282011-02-10 22:38:50 -0300477 }
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200478 break;
479
480 case L2CAP_CHAN_CONN_LESS:
Marcel Holtmann01394182006-07-03 10:02:46 +0200481 /* Connectionless socket */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300482 chan->scid = L2CAP_CID_CONN_LESS;
483 chan->dcid = L2CAP_CID_CONN_LESS;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300484 chan->omtu = L2CAP_DEFAULT_MTU;
Andrei Emeltchenko54911202012-02-06 15:04:00 +0200485 break;
486
487 default:
Marcel Holtmann01394182006-07-03 10:02:46 +0200488 /* Raw socket can send/recv signalling messages only */
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300489 chan->scid = L2CAP_CID_SIGNALING;
490 chan->dcid = L2CAP_CID_SIGNALING;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300491 chan->omtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann01394182006-07-03 10:02:46 +0200492 }
493
Andrei Emeltchenko8f7975b2011-10-13 16:18:54 +0300494 chan->local_id = L2CAP_BESTEFFORT_ID;
495 chan->local_stype = L2CAP_SERV_BESTEFFORT;
496 chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE;
497 chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME;
498 chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT;
499 chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO;
500
Ulisses Furquim371fd832011-12-21 20:02:36 -0200501 l2cap_chan_hold(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300502
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200503 list_add(&chan->list, &conn->chan_l);
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200504}
505
Andrei Emeltchenko14a28492012-03-23 16:31:49 +0200506static void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
Andrei Emeltchenko643162a2012-02-22 17:11:55 +0200507{
508 mutex_lock(&conn->chan_lock);
509 __l2cap_chan_add(conn, chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200510 mutex_unlock(&conn->chan_lock);
Marcel Holtmann01394182006-07-03 10:02:46 +0200511}
512
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300513static void l2cap_chan_del(struct l2cap_chan *chan, int err)
Marcel Holtmann01394182006-07-03 10:02:46 +0200514{
Gustavo F. Padovan48454072011-03-25 00:22:30 -0300515 struct sock *sk = chan->sk;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300516 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann01394182006-07-03 10:02:46 +0200517 struct sock *parent = bt_sk(sk)->parent;
518
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300519 __clear_chan_timer(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +0200520
Gustavo F. Padovan49208c92011-04-04 15:59:54 -0300521 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200522
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900523 if (conn) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300524 /* Delete from channel list */
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200525 list_del(&chan->list);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -0200526
Ulisses Furquim371fd832011-12-21 20:02:36 -0200527 l2cap_chan_put(chan);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -0300528
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300529 chan->conn = NULL;
Marcel Holtmann01394182006-07-03 10:02:46 +0200530 hci_conn_put(conn->hcon);
531 }
532
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200533 lock_sock(sk);
534
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200535 __l2cap_state_change(chan, BT_CLOSED);
Marcel Holtmann01394182006-07-03 10:02:46 +0200536 sock_set_flag(sk, SOCK_ZAPPED);
537
538 if (err)
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +0200539 __l2cap_chan_set_err(chan, err);
Marcel Holtmann01394182006-07-03 10:02:46 +0200540
541 if (parent) {
542 bt_accept_unlink(sk);
543 parent->sk_data_ready(parent, 0);
544 } else
545 sk->sk_state_change(sk);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300546
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200547 release_sock(sk);
548
Mat Martineau28270112012-05-17 21:14:09 -0700549 if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
Gustavo F. Padovan6ff5abb2011-04-25 15:10:41 -0300550 return;
Gustavo F. Padovan2ead70b2011-04-01 15:13:36 -0300551
Gustavo F. Padovan58d35f82011-04-04 16:16:44 -0300552 skb_queue_purge(&chan->tx_q);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300553
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -0300554 if (chan->mode == 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 F. Padovanc13ffa62010-05-13 20:50:12 -0300563 }
Marcel Holtmann01394182006-07-03 10:02:46 +0200564}
565
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300566static void l2cap_chan_cleanup_listen(struct sock *parent)
567{
568 struct sock *sk;
569
570 BT_DBG("parent %p", parent);
571
572 /* Close not yet accepted channels */
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300573 while ((sk = bt_accept_dequeue(parent, NULL))) {
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -0300574 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200575
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200576 l2cap_chan_lock(chan);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300577 __clear_chan_timer(chan);
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -0300578 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200579 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +0200580
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -0300581 chan->ops->close(chan->data);
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300582 }
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300583}
584
Gustavo F. Padovan0f852722011-05-04 19:42:50 -0300585void l2cap_chan_close(struct l2cap_chan *chan, int reason)
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300586{
587 struct l2cap_conn *conn = chan->conn;
588 struct sock *sk = chan->sk;
589
Andrei Emeltchenkoe05dcc32012-02-17 11:40:56 +0200590 BT_DBG("chan %p state %s sk %p", chan,
591 state_to_string(chan->state), sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300592
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300593 switch (chan->state) {
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300594 case BT_LISTEN:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200595 lock_sock(sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300596 l2cap_chan_cleanup_listen(sk);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300597
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +0200598 __l2cap_state_change(chan, BT_CLOSED);
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300599 sock_set_flag(sk, SOCK_ZAPPED);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200600 release_sock(sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300601 break;
602
603 case BT_CONNECTED:
604 case BT_CONFIG:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300605 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300606 conn->hcon->type == ACL_LINK) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -0300607 __set_chan_timer(chan, sk->sk_sndtimeo);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300608 l2cap_send_disconn_req(conn, chan, reason);
609 } else
610 l2cap_chan_del(chan, reason);
611 break;
612
613 case BT_CONNECT2:
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300614 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300615 conn->hcon->type == ACL_LINK) {
616 struct l2cap_conn_rsp rsp;
617 __u16 result;
618
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300619 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300620 result = L2CAP_CR_SEC_BLOCK;
621 else
622 result = L2CAP_CR_BAD_PSM;
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -0300623 l2cap_state_change(chan, BT_DISCONN);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300624
625 rsp.scid = cpu_to_le16(chan->dcid);
626 rsp.dcid = cpu_to_le16(chan->scid);
627 rsp.result = cpu_to_le16(result);
628 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
629 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
630 sizeof(rsp), &rsp);
631 }
632
633 l2cap_chan_del(chan, reason);
634 break;
635
636 case BT_CONNECT:
637 case BT_DISCONN:
638 l2cap_chan_del(chan, reason);
639 break;
640
641 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200642 lock_sock(sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300643 sock_set_flag(sk, SOCK_ZAPPED);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +0200644 release_sock(sk);
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300645 break;
646 }
647}
648
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300649static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530650{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -0300651 if (chan->chan_type == L2CAP_CHAN_RAW) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300652 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530653 case BT_SECURITY_HIGH:
654 return HCI_AT_DEDICATED_BONDING_MITM;
655 case BT_SECURITY_MEDIUM:
656 return HCI_AT_DEDICATED_BONDING;
657 default:
658 return HCI_AT_NO_BONDING;
659 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300660 } else if (chan->psm == cpu_to_le16(0x0001)) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300661 if (chan->sec_level == BT_SECURITY_LOW)
662 chan->sec_level = BT_SECURITY_SDP;
Johan Hedberg8556edd32011-01-19 12:06:50 +0530663
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300664 if (chan->sec_level == BT_SECURITY_HIGH)
Johan Hedberg8556edd32011-01-19 12:06:50 +0530665 return HCI_AT_NO_BONDING_MITM;
666 else
667 return HCI_AT_NO_BONDING;
668 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300669 switch (chan->sec_level) {
Johan Hedberg8556edd32011-01-19 12:06:50 +0530670 case BT_SECURITY_HIGH:
671 return HCI_AT_GENERAL_BONDING_MITM;
672 case BT_SECURITY_MEDIUM:
673 return HCI_AT_GENERAL_BONDING;
674 default:
675 return HCI_AT_NO_BONDING;
676 }
677 }
678}
679
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200680/* Service level security */
Gustavo F. Padovand45fc422011-11-05 19:54:24 -0200681int l2cap_chan_check_security(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200682{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -0300683 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100684 __u8 auth_type;
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200685
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300686 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100687
Gustavo F. Padovan43434782011-04-12 18:31:57 -0300688 return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
Marcel Holtmann79d554a2008-07-14 20:13:44 +0200689}
690
Johannes Bergb5ad8b72011-06-01 08:54:45 +0200691static u8 l2cap_get_ident(struct l2cap_conn *conn)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200692{
693 u8 id;
694
695 /* Get next available identificator.
696 * 1 - 128 are used by kernel.
697 * 129 - 199 are reserved.
698 * 200 - 254 are used by utilities like l2ping, etc.
699 */
700
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200701 spin_lock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200702
703 if (++conn->tx_ident > 128)
704 conn->tx_ident = 1;
705
706 id = conn->tx_ident;
707
Gustavo F. Padovan333055f2011-12-22 15:14:39 -0200708 spin_unlock(&conn->lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200709
710 return id;
711}
712
Gustavo F. Padovan4519de92011-04-28 17:55:53 -0300713static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200714{
715 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200716 u8 flags;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200717
718 BT_DBG("code 0x%2.2x", code);
719
720 if (!skb)
Gustavo F. Padovan9a9c6a32010-05-01 16:15:43 -0300721 return;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200722
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +0200723 if (lmp_no_flush_capable(conn->hcon->hdev))
724 flags = ACL_START_NO_FLUSH;
725 else
726 flags = ACL_START;
727
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700728 bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +0200729 skb->priority = HCI_PRIO_MAX;
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700730
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200731 hci_send_acl(conn->hchan, skb, flags);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +0200732}
733
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200734static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
735{
736 struct hci_conn *hcon = chan->conn->hcon;
737 u16 flags;
738
739 BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
740 skb->priority);
741
742 if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
743 lmp_no_flush_capable(hcon->hdev))
744 flags = ACL_START_NO_FLUSH;
745 else
746 flags = ACL_START;
747
748 bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
749 hci_send_acl(chan->conn->hchan, skb, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750}
751
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700752static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
753{
754 control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
755 control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
756
757 if (enh & L2CAP_CTRL_FRAME_TYPE) {
758 /* S-Frame */
759 control->sframe = 1;
760 control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
761 control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
762
763 control->sar = 0;
764 control->txseq = 0;
765 } else {
766 /* I-Frame */
767 control->sframe = 0;
768 control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
769 control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
770
771 control->poll = 0;
772 control->super = 0;
773 }
774}
775
776static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
777{
778 control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
779 control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
780
781 if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
782 /* S-Frame */
783 control->sframe = 1;
784 control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
785 control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
786
787 control->sar = 0;
788 control->txseq = 0;
789 } else {
790 /* I-Frame */
791 control->sframe = 0;
792 control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
793 control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
794
795 control->poll = 0;
796 control->super = 0;
797 }
798}
799
800static inline void __unpack_control(struct l2cap_chan *chan,
801 struct sk_buff *skb)
802{
803 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
804 __unpack_extended_control(get_unaligned_le32(skb->data),
805 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700806 skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700807 } else {
808 __unpack_enhanced_control(get_unaligned_le16(skb->data),
809 &bt_cb(skb)->control);
Mat Martineaucec8ab6e2012-05-17 20:53:36 -0700810 skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
Mat Martineaub5c6aae2012-04-25 16:36:15 -0700811 }
812}
813
814static u32 __pack_extended_control(struct l2cap_ctrl *control)
815{
816 u32 packed;
817
818 packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
819 packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
820
821 if (control->sframe) {
822 packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
823 packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
824 packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
825 } else {
826 packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
827 packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
828 }
829
830 return packed;
831}
832
833static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
834{
835 u16 packed;
836
837 packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
838 packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
839
840 if (control->sframe) {
841 packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
842 packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
843 packed |= L2CAP_CTRL_FRAME_TYPE;
844 } else {
845 packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
846 packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
847 }
848
849 return packed;
850}
851
852static inline void __pack_control(struct l2cap_chan *chan,
853 struct l2cap_ctrl *control,
854 struct sk_buff *skb)
855{
856 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
857 put_unaligned_le32(__pack_extended_control(control),
858 skb->data + L2CAP_HDR_SIZE);
859 } else {
860 put_unaligned_le16(__pack_enhanced_control(control),
861 skb->data + L2CAP_HDR_SIZE);
862 }
863}
864
Mat Martineaua67d7f62012-05-17 20:53:35 -0700865static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
866 u32 control)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300867{
868 struct sk_buff *skb;
869 struct l2cap_hdr *lh;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700870 int hlen;
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -0300871
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +0300872 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
873 hlen = L2CAP_EXT_HDR_SIZE;
874 else
875 hlen = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300876
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300877 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300878 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300879
Mat Martineaua67d7f62012-05-17 20:53:35 -0700880 skb = bt_skb_alloc(hlen, GFP_KERNEL);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300881
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300882 if (!skb)
Mat Martineaua67d7f62012-05-17 20:53:35 -0700883 return ERR_PTR(-ENOMEM);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300884
885 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300886 lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -0300887 lh->cid = cpu_to_le16(chan->dcid);
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +0300888
Mat Martineaua67d7f62012-05-17 20:53:35 -0700889 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
890 put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
891 else
892 put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300893
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -0300894 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineaua67d7f62012-05-17 20:53:35 -0700895 u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +0300896 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -0300897 }
898
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200899 skb->priority = HCI_PRIO_MAX;
Mat Martineaua67d7f62012-05-17 20:53:35 -0700900 return skb;
901}
902
903static void l2cap_send_sframe(struct l2cap_chan *chan,
904 struct l2cap_ctrl *control)
905{
906 struct sk_buff *skb;
907 u32 control_field;
908
909 BT_DBG("chan %p, control %p", chan, control);
910
911 if (!control->sframe)
912 return;
913
914 if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
915 !control->poll)
916 control->final = 1;
917
918 if (control->super == L2CAP_SUPER_RR)
919 clear_bit(CONN_RNR_SENT, &chan->conn_state);
920 else if (control->super == L2CAP_SUPER_RNR)
921 set_bit(CONN_RNR_SENT, &chan->conn_state);
922
923 if (control->super != L2CAP_SUPER_SREJ) {
924 chan->last_acked_seq = control->reqseq;
925 __clear_ack_timer(chan);
926 }
927
928 BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
929 control->final, control->poll, control->super);
930
931 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
932 control_field = __pack_extended_control(control);
933 else
934 control_field = __pack_enhanced_control(control);
935
936 skb = l2cap_create_sframe_pdu(chan, control_field);
937 if (!IS_ERR(skb))
938 l2cap_do_send(chan, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -0300939}
940
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700941static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300942{
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700943 struct l2cap_ctrl control;
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300944
Mat Martineauc9e3d5e2012-05-17 20:53:48 -0700945 BT_DBG("chan %p, poll %d", chan, poll);
946
947 memset(&control, 0, sizeof(control));
948 control.sframe = 1;
949 control.poll = poll;
950
951 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
952 control.super = L2CAP_SUPER_RNR;
953 else
954 control.super = L2CAP_SUPER_RR;
955
956 control.reqseq = chan->buffer_seq;
957 l2cap_send_sframe(chan, &control);
Gustavo F. Padovan7e743092009-08-26 04:04:03 -0300958}
959
Gustavo F. Padovanb4450032011-04-12 18:15:09 -0300960static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300961{
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -0300962 return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
Andrei Emeltchenkoe501d052010-07-08 12:14:41 +0300963}
964
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +0200965static void l2cap_send_conn_req(struct l2cap_chan *chan)
966{
967 struct l2cap_conn *conn = chan->conn;
968 struct l2cap_conn_req req;
969
970 req.scid = cpu_to_le16(chan->scid);
971 req.psm = chan->psm;
972
973 chan->ident = l2cap_get_ident(conn);
974
975 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
976
977 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
978}
979
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300980static void l2cap_chan_ready(struct l2cap_chan *chan)
981{
982 struct sock *sk = chan->sk;
983 struct sock *parent;
984
985 lock_sock(sk);
986
987 parent = bt_sk(sk)->parent;
988
989 BT_DBG("sk %p, parent %p", sk, parent);
990
Mat Martineau28270112012-05-17 21:14:09 -0700991 /* This clears all conf flags, including CONF_NOT_COMPLETE */
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -0300992 chan->conf_state = 0;
993 __clear_chan_timer(chan);
994
995 __l2cap_state_change(chan, BT_CONNECTED);
996 sk->sk_state_change(sk);
997
998 if (parent)
999 parent->sk_data_ready(parent, 0);
1000
1001 release_sock(sk);
1002}
1003
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001004static void l2cap_do_start(struct l2cap_chan *chan)
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001005{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001006 struct l2cap_conn *conn = chan->conn;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001007
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001008 if (conn->hcon->type == LE_LINK) {
1009 l2cap_chan_ready(chan);
1010 return;
1011 }
1012
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001013 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
Marcel Holtmann984947d2009-02-06 23:35:19 +01001014 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1015 return;
1016
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001017 if (l2cap_chan_check_security(chan) &&
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001018 __l2cap_no_conn_pending(chan))
1019 l2cap_send_conn_req(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001020 } else {
1021 struct l2cap_info_req req;
1022 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
1023
1024 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1025 conn->info_ident = l2cap_get_ident(conn);
1026
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08001027 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001028
1029 l2cap_send_cmd(conn, conn->info_ident,
1030 L2CAP_INFO_REQ, sizeof(req), &req);
1031 }
1032}
1033
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001034static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1035{
1036 u32 local_feat_mask = l2cap_feat_mask;
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03001037 if (!disable_ertm)
Gustavo F. Padovancf6c2c02010-06-07 20:54:45 -03001038 local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
1039
1040 switch (mode) {
1041 case L2CAP_MODE_ERTM:
1042 return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
1043 case L2CAP_MODE_STREAMING:
1044 return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
1045 default:
1046 return 0x00;
1047 }
1048}
1049
Gustavo F. Padovan4519de92011-04-28 17:55:53 -03001050static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err)
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001051{
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001052 struct sock *sk = chan->sk;
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001053 struct l2cap_disconn_req req;
1054
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001055 if (!conn)
1056 return;
1057
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03001058 if (chan->mode == L2CAP_MODE_ERTM) {
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001059 __clear_retrans_timer(chan);
1060 __clear_monitor_timer(chan);
1061 __clear_ack_timer(chan);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001062 }
1063
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001064 req.dcid = cpu_to_le16(chan->dcid);
1065 req.scid = cpu_to_le16(chan->scid);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001066 l2cap_send_cmd(conn, l2cap_get_ident(conn),
1067 L2CAP_DISCONN_REQ, sizeof(req), &req);
Gustavo F. Padovanc13ffa62010-05-13 20:50:12 -03001068
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001069 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001070 __l2cap_state_change(chan, BT_DISCONN);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001071 __l2cap_chan_set_err(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001072 release_sock(sk);
Gustavo F. Padovan22121fc2009-07-23 10:27:23 -03001073}
1074
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075/* ---- L2CAP connections ---- */
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001076static void l2cap_conn_start(struct l2cap_conn *conn)
1077{
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001078 struct l2cap_chan *chan, *tmp;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001079
1080 BT_DBG("conn %p", conn);
1081
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001082 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001083
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001084 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001085 struct sock *sk = chan->sk;
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001086
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001087 l2cap_chan_lock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001088
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001089 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001090 l2cap_chan_unlock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001091 continue;
1092 }
1093
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001094 if (chan->state == BT_CONNECT) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001095 if (!l2cap_chan_check_security(chan) ||
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03001096 !__l2cap_no_conn_pending(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001097 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001098 continue;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02001099 }
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001100
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03001101 if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
1102 && test_bit(CONF_STATE2_DEVICE,
1103 &chan->conf_state)) {
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001104 l2cap_chan_close(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001105 l2cap_chan_unlock(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001106 continue;
1107 }
1108
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02001109 l2cap_send_conn_req(chan);
Gustavo F. Padovan47731de2010-07-09 16:38:35 -03001110
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001111 } else if (chan->state == BT_CONNECT2) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001112 struct l2cap_conn_rsp rsp;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03001113 char buf[128];
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001114 rsp.scid = cpu_to_le16(chan->dcid);
1115 rsp.dcid = cpu_to_le16(chan->scid);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001116
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001117 if (l2cap_chan_check_security(chan)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001118 lock_sock(sk);
Gustavo Padovanc5daa682012-05-16 12:17:10 -03001119 if (test_bit(BT_SK_DEFER_SETUP,
1120 &bt_sk(sk)->flags)) {
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001121 struct sock *parent = bt_sk(sk)->parent;
1122 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
1123 rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
Ilia Kolomisnky05e9a2f2011-07-15 18:30:21 +00001124 if (parent)
1125 parent->sk_data_ready(parent, 0);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001126
1127 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001128 __l2cap_state_change(chan, BT_CONFIG);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01001129 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1130 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
1131 }
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001132 release_sock(sk);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001133 } else {
1134 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
1135 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
1136 }
1137
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001138 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
1139 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 F. Padovane9aeb2d2010-07-08 20:08:18 -03001142 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 F. Padovan73ffa902011-03-25 14:16:54 -03001149 l2cap_build_conf_req(chan, buf), buf);
1150 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. Padovan89bc5002011-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
Ville Tervob62f3282011-02-10 22:38:50 -03001219 /* Check for backlog size */
1220 if (sk_acceptq_is_full(parent)) {
1221 BT_DBG("backlog full %d", parent->sk_ack_backlog);
1222 goto clean;
1223 }
1224
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001225 chan = pchan->ops->new_connection(pchan->data);
1226 if (!chan)
Ville Tervob62f3282011-02-10 22:38:50 -03001227 goto clean;
1228
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03001229 sk = chan->sk;
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001230
Ville Tervob62f3282011-02-10 22:38:50 -03001231 hci_conn_hold(conn->hcon);
1232
Ville Tervob62f3282011-02-10 22:38:50 -03001233 bacpy(&bt_sk(sk)->src, conn->src);
1234 bacpy(&bt_sk(sk)->dst, conn->dst);
1235
Gustavo F. Padovand1010242011-03-25 00:39:48 -03001236 bt_accept_enqueue(parent, sk);
1237
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02001238 l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001239
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001240 __set_chan_timer(chan, sk->sk_sndtimeo);
Ville Tervob62f3282011-02-10 22:38:50 -03001241
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001242 __l2cap_state_change(chan, BT_CONNECTED);
Ville Tervob62f3282011-02-10 22:38:50 -03001243 parent->sk_data_ready(parent, 0);
1244
Ville Tervob62f3282011-02-10 22:38:50 -03001245clean:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03001246 release_sock(parent);
Ville Tervob62f3282011-02-10 22:38:50 -03001247}
1248
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001249static void l2cap_conn_ready(struct l2cap_conn *conn)
1250{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001251 struct l2cap_chan *chan;
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001252
1253 BT_DBG("conn %p", conn);
1254
Ville Tervob62f3282011-02-10 22:38:50 -03001255 if (!conn->hcon->out && conn->hcon->type == LE_LINK)
1256 l2cap_le_conn_ready(conn);
1257
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03001258 if (conn->hcon->out && conn->hcon->type == LE_LINK)
1259 smp_conn_security(conn, conn->hcon->pending_sec_level);
1260
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001261 mutex_lock(&conn->chan_lock);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001262
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001263 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001264
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001265 l2cap_chan_lock(chan);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001266
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001267 if (conn->hcon->type == LE_LINK) {
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001268 if (smp_conn_security(conn, chan->sec_level))
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02001269 l2cap_chan_ready(chan);
Ville Tervoacd7d372011-02-10 22:38:49 -03001270
Vinicius Costa Gomes63128452011-06-17 22:46:26 -03001271 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001272 struct sock *sk = chan->sk;
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001273 __clear_chan_timer(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001274 lock_sock(sk);
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02001275 __l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001276 sk->sk_state_change(sk);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001277 release_sock(sk);
Anderson Brigliab501d6a2011-06-07 18:46:31 -03001278
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001279 } else if (chan->state == BT_CONNECT)
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001280 l2cap_do_start(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001281
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001282 l2cap_chan_unlock(chan);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001283 }
1284
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001285 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001286}
1287
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001288/* Notify sockets that we cannot guaranty reliability anymore */
1289static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
1290{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001291 struct l2cap_chan *chan;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001292
1293 BT_DBG("conn %p", conn);
1294
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001295 mutex_lock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001296
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001297 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenkoecf61bd2011-10-11 14:04:32 +03001298 if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02001299 __l2cap_chan_set_err(chan, err);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001300 }
1301
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001302 mutex_unlock(&conn->chan_lock);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001303}
1304
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001305static void l2cap_info_timeout(struct work_struct *work)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001306{
Gustavo F. Padovanf878fca2011-12-15 01:16:14 -02001307 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001308 info_timer.work);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001309
Marcel Holtmann984947d2009-02-06 23:35:19 +01001310 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01001311 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01001312
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001313 l2cap_conn_start(conn);
1314}
1315
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001316static void l2cap_conn_del(struct hci_conn *hcon, int err)
1317{
1318 struct l2cap_conn *conn = hcon->l2cap_data;
1319 struct l2cap_chan *chan, *l;
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001320
1321 if (!conn)
1322 return;
1323
1324 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1325
1326 kfree_skb(conn->rx_skb);
1327
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001328 mutex_lock(&conn->chan_lock);
1329
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001330 /* Kill channels */
1331 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
Mat Martineau61d6ef32012-04-27 16:50:50 -07001332 l2cap_chan_hold(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001333 l2cap_chan_lock(chan);
1334
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001335 l2cap_chan_del(chan, err);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001336
1337 l2cap_chan_unlock(chan);
1338
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001339 chan->ops->close(chan->data);
Mat Martineau61d6ef32012-04-27 16:50:50 -07001340 l2cap_chan_put(chan);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001341 }
1342
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001343 mutex_unlock(&conn->chan_lock);
1344
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001345 hci_chan_del(conn->hchan);
1346
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001347 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
Ulisses Furquim127074b2012-01-30 18:26:29 -02001348 cancel_delayed_work_sync(&conn->info_timer);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001349
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001350 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
Ulisses Furquim127074b2012-01-30 18:26:29 -02001351 cancel_delayed_work_sync(&conn->security_timer);
Vinicius Costa Gomes8aab4752011-09-05 14:31:31 -03001352 smp_chan_destroy(conn);
Vinicius Costa Gomesd26a2342011-08-19 21:06:51 -03001353 }
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001354
1355 hcon->l2cap_data = NULL;
1356 kfree(conn);
1357}
1358
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001359static void security_timeout(struct work_struct *work)
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001360{
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001361 struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
1362 security_timer.work);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001363
1364 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1365}
1366
Linus Torvalds1da177e2005-04-16 15:20:36 -07001367static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
1368{
Marcel Holtmann01394182006-07-03 10:02:46 +02001369 struct l2cap_conn *conn = hcon->l2cap_data;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001370 struct hci_chan *hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001371
Marcel Holtmann01394182006-07-03 10:02:46 +02001372 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373 return conn;
1374
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001375 hchan = hci_chan_create(hcon);
1376 if (!hchan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001379 conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC);
1380 if (!conn) {
1381 hci_chan_del(hchan);
1382 return NULL;
1383 }
1384
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385 hcon->l2cap_data = conn;
1386 conn->hcon = hcon;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001387 conn->hchan = hchan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001388
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +02001389 BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
Marcel Holtmann01394182006-07-03 10:02:46 +02001390
Ville Tervoacd7d372011-02-10 22:38:49 -03001391 if (hcon->hdev->le_mtu && hcon->type == LE_LINK)
1392 conn->mtu = hcon->hdev->le_mtu;
1393 else
1394 conn->mtu = hcon->hdev->acl_mtu;
1395
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396 conn->src = &hcon->hdev->bdaddr;
1397 conn->dst = &hcon->dst;
1398
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02001399 conn->feat_mask = 0;
1400
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401 spin_lock_init(&conn->lock);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02001402 mutex_init(&conn->chan_lock);
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03001403
1404 INIT_LIST_HEAD(&conn->chan_l);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001406 if (hcon->type == LE_LINK)
Gustavo F. Padovan6c9d42a2011-12-20 10:57:27 -02001407 INIT_DELAYED_WORK(&conn->security_timer, security_timeout);
Vinicius Costa Gomes5d3de7d2011-06-14 13:37:41 -03001408 else
Gustavo F. Padovan030013d2011-12-20 10:57:28 -02001409 INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
Dave Young45054dc2009-10-18 20:28:30 +00001410
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001411 conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01001412
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413 return conn;
1414}
1415
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416/* ---- Socket interface ---- */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001417
Ido Yarivc2287682012-04-20 15:46:07 -03001418/* Find socket with psm and source / destination bdaddr.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419 * Returns closest match.
1420 */
Ido Yarivc2287682012-04-20 15:46:07 -03001421static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1422 bdaddr_t *src,
1423 bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001425 struct l2cap_chan *c, *c1 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001427 read_lock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001428
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001429 list_for_each_entry(c, &chan_list, global_l) {
1430 struct sock *sk = c->sk;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001431
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03001432 if (state && c->state != state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001433 continue;
1434
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001435 if (c->psm == psm) {
Ido Yarivc2287682012-04-20 15:46:07 -03001436 int src_match, dst_match;
1437 int src_any, dst_any;
1438
Linus Torvalds1da177e2005-04-16 15:20:36 -07001439 /* Exact match. */
Ido Yarivc2287682012-04-20 15:46:07 -03001440 src_match = !bacmp(&bt_sk(sk)->src, src);
1441 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1442 if (src_match && dst_match) {
Johannes Berga7567b22011-06-01 08:29:54 +02001443 read_unlock(&chan_list_lock);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001444 return c;
1445 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446
1447 /* Closest match */
Ido Yarivc2287682012-04-20 15:46:07 -03001448 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1449 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1450 if ((src_match && dst_any) || (src_any && dst_match) ||
1451 (src_any && dst_any))
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001452 c1 = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453 }
1454 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001456 read_unlock(&chan_list_lock);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00001457
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03001458 return c1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459}
1460
Andre Guedes8e9f9892012-04-24 21:02:55 -03001461int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1462 bdaddr_t *dst, u8 dst_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463{
Gustavo F. Padovan5d41ce12011-04-08 15:40:02 -03001464 struct sock *sk = chan->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466 struct l2cap_conn *conn;
1467 struct hci_conn *hcon;
1468 struct hci_dev *hdev;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001469 __u8 auth_type;
Marcel Holtmann44d0e482009-04-20 07:09:16 +02001470 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471
Andre Guedes8e9f9892012-04-24 21:02:55 -03001472 BT_DBG("%s -> %s (type %u) psm 0x%2.2x", batostr(src), batostr(dst),
1473 dst_type, __le16_to_cpu(chan->psm));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03001475 hdev = hci_get_route(dst, src);
1476 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001477 return -EHOSTUNREACH;
1478
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001479 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001481 l2cap_chan_lock(chan);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001482
1483 /* PSM must be odd and lsb of upper byte must be 0 */
1484 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
1485 chan->chan_type != L2CAP_CHAN_RAW) {
1486 err = -EINVAL;
1487 goto done;
1488 }
1489
1490 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) {
1491 err = -EINVAL;
1492 goto done;
1493 }
1494
1495 switch (chan->mode) {
1496 case L2CAP_MODE_BASIC:
1497 break;
1498 case L2CAP_MODE_ERTM:
1499 case L2CAP_MODE_STREAMING:
1500 if (!disable_ertm)
1501 break;
1502 /* fall through */
1503 default:
1504 err = -ENOTSUPP;
1505 goto done;
1506 }
1507
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001508 lock_sock(sk);
1509
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001510 switch (sk->sk_state) {
1511 case BT_CONNECT:
1512 case BT_CONNECT2:
1513 case BT_CONFIG:
1514 /* Already connecting */
1515 err = 0;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001516 release_sock(sk);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001517 goto done;
1518
1519 case BT_CONNECTED:
1520 /* Already connected */
1521 err = -EISCONN;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001522 release_sock(sk);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001523 goto done;
1524
1525 case BT_OPEN:
1526 case BT_BOUND:
1527 /* Can connect */
1528 break;
1529
1530 default:
1531 err = -EBADFD;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001532 release_sock(sk);
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001533 goto done;
1534 }
1535
1536 /* Set destination address and psm */
Gustavo F. Padovan9219b2a2012-01-02 20:08:04 -02001537 bacpy(&bt_sk(sk)->dst, dst);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001538
1539 release_sock(sk);
1540
Gustavo F. Padovan03a00192011-12-09 04:48:17 -02001541 chan->psm = psm;
1542 chan->dcid = cid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001544 auth_type = l2cap_get_auth_type(chan);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +02001545
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03001546 if (chan->dcid == L2CAP_CID_LE_DATA)
Andre Guedes8e9f9892012-04-24 21:02:55 -03001547 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001548 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001549 else
Andre Guedes8e9f9892012-04-24 21:02:55 -03001550 hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
Andre Guedesb12f62c2012-04-24 21:02:54 -03001551 chan->sec_level, auth_type);
Ville Tervoacd7d372011-02-10 22:38:49 -03001552
Ville Tervo30e76272011-02-22 16:10:53 -03001553 if (IS_ERR(hcon)) {
1554 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001555 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -03001556 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557
1558 conn = l2cap_conn_add(hcon, 0);
1559 if (!conn) {
1560 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -03001561 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562 goto done;
1563 }
1564
Vinicius Costa Gomes9f0caeb2012-04-20 15:46:08 -03001565 if (hcon->type == LE_LINK) {
1566 err = 0;
1567
1568 if (!list_empty(&conn->chan_l)) {
1569 err = -EBUSY;
1570 hci_conn_put(hcon);
1571 }
1572
1573 if (err)
1574 goto done;
1575 }
1576
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 /* Update source addr of the socket */
1578 bacpy(src, conn->src);
1579
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001580 l2cap_chan_unlock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001581 l2cap_chan_add(conn, chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001582 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03001583
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001584 l2cap_state_change(chan, BT_CONNECT);
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001585 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586
1587 if (hcon->state == BT_CONNECTED) {
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03001588 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03001589 __clear_chan_timer(chan);
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02001590 if (l2cap_chan_check_security(chan))
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001591 l2cap_state_change(chan, BT_CONNECTED);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02001592 } else
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03001593 l2cap_do_start(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594 }
1595
Ville Tervo30e76272011-02-22 16:10:53 -03001596 err = 0;
1597
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001599 l2cap_chan_unlock(chan);
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -03001600 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601 hci_dev_put(hdev);
1602 return err;
1603}
1604
Gustavo F. Padovandcba0db2011-02-04 03:08:36 -02001605int __l2cap_wait_ack(struct sock *sk)
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001606{
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001607 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001608 DECLARE_WAITQUEUE(wait, current);
1609 int err = 0;
1610 int timeo = HZ/5;
1611
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001612 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001613 set_current_state(TASK_INTERRUPTIBLE);
1614 while (chan->unacked_frames > 0 && chan->conn) {
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001615 if (!timeo)
1616 timeo = HZ/5;
1617
1618 if (signal_pending(current)) {
1619 err = sock_intr_errno(timeo);
1620 break;
1621 }
1622
1623 release_sock(sk);
1624 timeo = schedule_timeout(timeo);
1625 lock_sock(sk);
Peter Hurleya71a0cf2011-07-25 18:36:26 -04001626 set_current_state(TASK_INTERRUPTIBLE);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001627
1628 err = sock_error(sk);
1629 if (err)
1630 break;
1631 }
1632 set_current_state(TASK_RUNNING);
Marcel Holtmann2b0b05d2010-05-10 11:33:10 +02001633 remove_wait_queue(sk_sleep(sk), &wait);
Gustavo F. Padovan6161c032010-05-01 16:15:44 -03001634 return err;
1635}
1636
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001637static void l2cap_monitor_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001638{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001639 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001640 monitor_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001641
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001642 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001643
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001644 l2cap_chan_lock(chan);
1645
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03001646 if (chan->retry_count >= chan->remote_max_tx) {
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03001647 l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001648 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001649 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001650 return;
1651 }
1652
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03001653 chan->retry_count++;
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001654 __set_monitor_timer(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001655
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001656 l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001657 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001658 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001659}
1660
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001661static void l2cap_retrans_timeout(struct work_struct *work)
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001662{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03001663 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
Mat Martineau4239d162012-05-17 20:53:49 -07001664 retrans_timer.work);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001665
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03001666 BT_DBG("chan %p", chan);
Gustavo F. Padovan0e989582010-04-19 14:45:38 -03001667
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001668 l2cap_chan_lock(chan);
1669
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03001670 chan->retry_count = 1;
Gustavo F. Padovan1a09bcb2011-05-17 15:13:19 -03001671 __set_monitor_timer(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001672
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03001673 set_bit(CONN_WAIT_F, &chan->conn_state);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001674
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03001675 l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02001676
1677 l2cap_chan_unlock(chan);
Andrei Emeltchenko8d7e1c72012-03-23 09:42:15 +02001678 l2cap_chan_put(chan);
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03001679}
1680
Mat Martineau37339372012-05-17 20:53:33 -07001681static int l2cap_streaming_send(struct l2cap_chan *chan,
1682 struct sk_buff_head *skbs)
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001683{
Gustavo F. Padovanccbb84a2010-08-30 18:44:44 -03001684 struct sk_buff *skb;
Mat Martineau37339372012-05-17 20:53:33 -07001685 struct l2cap_ctrl *control;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001686
Mat Martineau37339372012-05-17 20:53:33 -07001687 BT_DBG("chan %p, skbs %p", chan, skbs);
1688
1689 if (chan->state != BT_CONNECTED)
1690 return -ENOTCONN;
1691
1692 skb_queue_splice_tail_init(skbs, &chan->tx_q);
1693
1694 while (!skb_queue_empty(&chan->tx_q)) {
1695
1696 skb = skb_dequeue(&chan->tx_q);
1697
1698 bt_cb(skb)->control.retries = 1;
1699 control = &bt_cb(skb)->control;
1700
1701 control->reqseq = 0;
1702 control->txseq = chan->next_tx_seq;
1703
1704 __pack_control(chan, control, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001705
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03001706 if (chan->fcs == L2CAP_FCS_CRC16) {
Mat Martineau37339372012-05-17 20:53:33 -07001707 u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
1708 put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03001709 }
1710
Gustavo F. Padovan43434782011-04-12 18:31:57 -03001711 l2cap_do_send(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001712
Mat Martineau37339372012-05-17 20:53:33 -07001713 BT_DBG("Sent txseq %d", (int)control->txseq);
1714
Andrei Emeltchenko836be932011-10-17 12:19:57 +03001715 chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
Mat Martineau37339372012-05-17 20:53:33 -07001716 chan->frames_sent++;
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03001717 }
Mat Martineau37339372012-05-17 20:53:33 -07001718
1719 return 0;
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. Padovan89bc5002011-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);
1780 BT_DBG("Sent txseq %d", (int)control->txseq);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03001781 }
1782
Mat Martineau18a48e72012-05-17 20:53:34 -07001783 BT_DBG("Sent %d, %d unacked, %d in ERTM queue", sent,
1784 (int) chan->unacked_frames, skb_queue_len(&chan->tx_q));
1785
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",
1807 seq);
1808 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 */
1832 tx_skb = skb_copy(skb, GFP_ATOMIC);
1833 } else {
1834 tx_skb = skb_clone(skb, GFP_ATOMIC);
1835 }
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 ||
1892 skb == chan->tx_send_head)
1893 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
1935 /* Ack now if the tx window is 3/4ths full.
1936 * Calculate without mul or div
1937 */
1938 threshold = chan->tx_win;
1939 threshold += threshold << 1;
1940 threshold >>= 2;
1941
1942 BT_DBG("frames_to_ack %d, threshold %d", (int)frames_to_ack,
1943 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,
2004 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 Emeltchenko6d5922b2012-02-06 15:04:01 +02002012 BT_DBG("chan %p len %d priority %u", chan, (int)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,
2038 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 Emeltchenko6d5922b2012-02-06 15:04:01 +02002046 BT_DBG("chan %p len %d", chan, (int)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,
2071 struct msghdr *msg, size_t len,
Mat Martineau94122bb2012-05-02 09:42:02 -07002072 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 Emeltchenko6d5922b2012-02-06 15:04:01 +02002079 BT_DBG("chan %p len %d", chan, (int)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
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03002084 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2085 hlen = L2CAP_EXT_HDR_SIZE;
2086 else
2087 hlen = L2CAP_ENH_HDR_SIZE;
2088
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002089 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002090 hlen += L2CAP_SDULEN_SIZE;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002091
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002092 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002093 hlen += L2CAP_FCS_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002094
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002095 count = min_t(unsigned int, (conn->mtu - hlen), len);
Andrei Emeltchenko2f7719c2012-01-20 14:08:03 +02002096
2097 skb = chan->ops->alloc_skb(chan, count + hlen,
Gustavo Padovan90338942012-04-06 20:15:47 -03002098 msg->msg_flags & MSG_DONTWAIT);
2099 if (IS_ERR(skb))
2100 return skb;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002101
2102 /* Create L2CAP header */
2103 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002104 lh->cid = cpu_to_le16(chan->dcid);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002105 lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002106
Mat Martineau18a48e72012-05-17 20:53:34 -07002107 /* Control header is populated later */
2108 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2109 put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
2110 else
2111 put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
Andrei Emeltchenko88843ab2011-10-17 12:19:56 +03002112
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002113 if (sdulen)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03002114 put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002115
Andrei Emeltchenko0952a572012-01-13 17:21:43 +02002116 err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002117 if (unlikely(err < 0)) {
2118 kfree_skb(skb);
2119 return ERR_PTR(err);
2120 }
Gustavo F. Padovane90bac02009-08-20 22:26:00 -03002121
Mat Martineau18a48e72012-05-17 20:53:34 -07002122 bt_cb(skb)->control.fcs = chan->fcs;
Mat Martineau3ce35142012-04-25 16:36:14 -07002123 bt_cb(skb)->control.retries = 0;
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03002124 return skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002125}
2126
Mat Martineau94122bb2012-05-02 09:42:02 -07002127static int l2cap_segment_sdu(struct l2cap_chan *chan,
2128 struct sk_buff_head *seg_queue,
2129 struct msghdr *msg, size_t len)
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002130{
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002131 struct sk_buff *skb;
Mat Martineau94122bb2012-05-02 09:42:02 -07002132 u16 sdu_len;
2133 size_t pdu_len;
2134 int err = 0;
2135 u8 sar;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002136
Mat Martineau94122bb2012-05-02 09:42:02 -07002137 BT_DBG("chan %p, msg %p, len %d", chan, msg, (int)len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002138
Mat Martineau94122bb2012-05-02 09:42:02 -07002139 /* It is critical that ERTM PDUs fit in a single HCI fragment,
2140 * so fragmented skbs are not used. The HCI layer's handling
2141 * of fragmented skbs is not compatible with ERTM's queueing.
2142 */
2143
2144 /* PDU size is derived from the HCI MTU */
2145 pdu_len = chan->conn->mtu;
2146
2147 pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
2148
2149 /* Adjust for largest possible L2CAP overhead. */
2150 pdu_len -= L2CAP_EXT_HDR_SIZE + L2CAP_FCS_SIZE;
2151
2152 /* Remote device may have requested smaller PDUs */
2153 pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
2154
2155 if (len <= pdu_len) {
2156 sar = L2CAP_SAR_UNSEGMENTED;
2157 sdu_len = 0;
2158 pdu_len = len;
2159 } else {
2160 sar = L2CAP_SAR_START;
2161 sdu_len = len;
2162 pdu_len -= L2CAP_SDULEN_SIZE;
2163 }
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002164
2165 while (len > 0) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002166 skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002167
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002168 if (IS_ERR(skb)) {
Mat Martineau94122bb2012-05-02 09:42:02 -07002169 __skb_queue_purge(seg_queue);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002170 return PTR_ERR(skb);
2171 }
2172
Mat Martineau94122bb2012-05-02 09:42:02 -07002173 bt_cb(skb)->control.sar = sar;
2174 __skb_queue_tail(seg_queue, skb);
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002175
Mat Martineau94122bb2012-05-02 09:42:02 -07002176 len -= pdu_len;
2177 if (sdu_len) {
2178 sdu_len = 0;
2179 pdu_len += L2CAP_SDULEN_SIZE;
2180 }
2181
2182 if (len <= pdu_len) {
2183 sar = L2CAP_SAR_END;
2184 pdu_len = len;
2185 } else {
2186 sar = L2CAP_SAR_CONTINUE;
2187 }
2188 }
2189
2190 return err;
Gustavo F. Padovanc74e5602009-08-20 22:25:58 -03002191}
2192
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002193int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
2194 u32 priority)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002195{
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002196 struct sk_buff *skb;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002197 int err;
Mat Martineau94122bb2012-05-02 09:42:02 -07002198 struct sk_buff_head seg_queue;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002199
2200 /* Connectionless channel */
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002201 if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002202 skb = l2cap_create_connless_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002203 if (IS_ERR(skb))
2204 return PTR_ERR(skb);
2205
2206 l2cap_do_send(chan, skb);
2207 return len;
2208 }
2209
2210 switch (chan->mode) {
2211 case L2CAP_MODE_BASIC:
2212 /* Check outgoing MTU */
2213 if (len > chan->omtu)
2214 return -EMSGSIZE;
2215
2216 /* Create a basic PDU */
Luiz Augusto von Dentz5e59b792011-11-01 10:58:57 +02002217 skb = l2cap_create_basic_pdu(chan, msg, len, priority);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002218 if (IS_ERR(skb))
2219 return PTR_ERR(skb);
2220
2221 l2cap_do_send(chan, skb);
2222 err = len;
2223 break;
2224
2225 case L2CAP_MODE_ERTM:
2226 case L2CAP_MODE_STREAMING:
Mat Martineau94122bb2012-05-02 09:42:02 -07002227 /* Check outgoing MTU */
2228 if (len > chan->omtu) {
2229 err = -EMSGSIZE;
2230 break;
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002231 }
2232
Mat Martineau94122bb2012-05-02 09:42:02 -07002233 __skb_queue_head_init(&seg_queue);
2234
2235 /* Do segmentation before calling in to the state machine,
2236 * since it's possible to block while waiting for memory
2237 * allocation.
2238 */
2239 err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
2240
2241 /* The channel could have been closed while segmenting,
2242 * check that it is still connected.
2243 */
2244 if (chan->state != BT_CONNECTED) {
2245 __skb_queue_purge(&seg_queue);
2246 err = -ENOTCONN;
2247 }
2248
2249 if (err)
2250 break;
2251
Mat Martineau37339372012-05-17 20:53:33 -07002252 if (chan->mode == L2CAP_MODE_ERTM)
Mat Martineau608bcc62012-05-17 20:53:32 -07002253 err = l2cap_tx(chan, 0, &seg_queue,
2254 L2CAP_EV_DATA_REQUEST);
Mat Martineau37339372012-05-17 20:53:33 -07002255 else
2256 err = l2cap_streaming_send(chan, &seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002257
Mat Martineau608bcc62012-05-17 20:53:32 -07002258 if (!err)
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002259 err = len;
2260
Mat Martineau94122bb2012-05-02 09:42:02 -07002261 /* If the skbs were not queued for sending, they'll still be in
2262 * seg_queue and need to be purged.
2263 */
2264 __skb_queue_purge(&seg_queue);
Gustavo F. Padovan9a91a042011-04-28 18:50:17 -03002265 break;
2266
2267 default:
2268 BT_DBG("bad state %1.1x", chan->mode);
2269 err = -EBADFD;
2270 }
2271
2272 return err;
2273}
2274
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002275static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2276{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002277 struct l2cap_ctrl control;
2278 u16 seq;
2279
2280 BT_DBG("chan %p, txseq %d", chan, txseq);
2281
2282 memset(&control, 0, sizeof(control));
2283 control.sframe = 1;
2284 control.super = L2CAP_SUPER_SREJ;
2285
2286 for (seq = chan->expected_tx_seq; seq != txseq;
2287 seq = __next_seq(chan, seq)) {
2288 if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2289 control.reqseq = seq;
2290 l2cap_send_sframe(chan, &control);
2291 l2cap_seq_list_append(&chan->srej_list, seq);
2292 }
2293 }
2294
2295 chan->expected_tx_seq = __next_seq(chan, txseq);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002296}
2297
2298static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2299{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002300 struct l2cap_ctrl control;
2301
2302 BT_DBG("chan %p", chan);
2303
2304 if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2305 return;
2306
2307 memset(&control, 0, sizeof(control));
2308 control.sframe = 1;
2309 control.super = L2CAP_SUPER_SREJ;
2310 control.reqseq = chan->srej_list.tail;
2311 l2cap_send_sframe(chan, &control);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002312}
2313
2314static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2315{
Mat Martineaubed68bd2012-05-17 20:53:44 -07002316 struct l2cap_ctrl control;
2317 u16 initial_head;
2318 u16 seq;
2319
2320 BT_DBG("chan %p, txseq %d", chan, txseq);
2321
2322 memset(&control, 0, sizeof(control));
2323 control.sframe = 1;
2324 control.super = L2CAP_SUPER_SREJ;
2325
2326 /* Capture initial list head to allow only one pass through the list. */
2327 initial_head = chan->srej_list.head;
2328
2329 do {
2330 seq = l2cap_seq_list_pop(&chan->srej_list);
2331 if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2332 break;
2333
2334 control.reqseq = seq;
2335 l2cap_send_sframe(chan, &control);
2336 l2cap_seq_list_append(&chan->srej_list, seq);
2337 } while (chan->srej_list.head != initial_head);
Mat Martineaud2a7ac52012-05-17 20:53:42 -07002338}
2339
Mat Martineau608bcc62012-05-17 20:53:32 -07002340static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2341{
2342 struct sk_buff *acked_skb;
2343 u16 ackseq;
2344
2345 BT_DBG("chan %p, reqseq %d", chan, reqseq);
2346
2347 if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2348 return;
2349
2350 BT_DBG("expected_ack_seq %d, unacked_frames %d",
2351 chan->expected_ack_seq, chan->unacked_frames);
2352
2353 for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2354 ackseq = __next_seq(chan, ackseq)) {
2355
2356 acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2357 if (acked_skb) {
2358 skb_unlink(acked_skb, &chan->tx_q);
2359 kfree_skb(acked_skb);
2360 chan->unacked_frames--;
2361 }
2362 }
2363
2364 chan->expected_ack_seq = reqseq;
2365
2366 if (chan->unacked_frames == 0)
2367 __clear_retrans_timer(chan);
2368
2369 BT_DBG("unacked_frames %d", (int) chan->unacked_frames);
2370}
2371
2372static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
2373{
2374 BT_DBG("chan %p", chan);
2375
2376 chan->expected_tx_seq = chan->buffer_seq;
2377 l2cap_seq_list_clear(&chan->srej_list);
2378 skb_queue_purge(&chan->srej_q);
2379 chan->rx_state = L2CAP_RX_STATE_RECV;
2380}
2381
2382static int l2cap_tx_state_xmit(struct l2cap_chan *chan,
2383 struct l2cap_ctrl *control,
2384 struct sk_buff_head *skbs, u8 event)
2385{
2386 int err = 0;
2387
2388 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2389 event);
2390
2391 switch (event) {
2392 case L2CAP_EV_DATA_REQUEST:
2393 if (chan->tx_send_head == NULL)
2394 chan->tx_send_head = skb_peek(skbs);
2395
2396 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2397 l2cap_ertm_send(chan);
2398 break;
2399 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2400 BT_DBG("Enter LOCAL_BUSY");
2401 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2402
2403 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2404 /* The SREJ_SENT state must be aborted if we are to
2405 * enter the LOCAL_BUSY state.
2406 */
2407 l2cap_abort_rx_srej_sent(chan);
2408 }
2409
2410 l2cap_send_ack(chan);
2411
2412 break;
2413 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2414 BT_DBG("Exit LOCAL_BUSY");
2415 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2416
2417 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2418 struct l2cap_ctrl local_control;
2419
2420 memset(&local_control, 0, sizeof(local_control));
2421 local_control.sframe = 1;
2422 local_control.super = L2CAP_SUPER_RR;
2423 local_control.poll = 1;
2424 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002425 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002426
2427 chan->retry_count = 1;
2428 __set_monitor_timer(chan);
2429 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2430 }
2431 break;
2432 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2433 l2cap_process_reqseq(chan, control->reqseq);
2434 break;
2435 case L2CAP_EV_EXPLICIT_POLL:
2436 l2cap_send_rr_or_rnr(chan, 1);
2437 chan->retry_count = 1;
2438 __set_monitor_timer(chan);
2439 __clear_ack_timer(chan);
2440 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2441 break;
2442 case L2CAP_EV_RETRANS_TO:
2443 l2cap_send_rr_or_rnr(chan, 1);
2444 chan->retry_count = 1;
2445 __set_monitor_timer(chan);
2446 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2447 break;
2448 case L2CAP_EV_RECV_FBIT:
2449 /* Nothing to process */
2450 break;
2451 default:
2452 break;
2453 }
2454
2455 return err;
2456}
2457
2458static int l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2459 struct l2cap_ctrl *control,
2460 struct sk_buff_head *skbs, u8 event)
2461{
2462 int err = 0;
2463
2464 BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2465 event);
2466
2467 switch (event) {
2468 case L2CAP_EV_DATA_REQUEST:
2469 if (chan->tx_send_head == NULL)
2470 chan->tx_send_head = skb_peek(skbs);
2471 /* Queue data, but don't send. */
2472 skb_queue_splice_tail_init(skbs, &chan->tx_q);
2473 break;
2474 case L2CAP_EV_LOCAL_BUSY_DETECTED:
2475 BT_DBG("Enter LOCAL_BUSY");
2476 set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2477
2478 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2479 /* The SREJ_SENT state must be aborted if we are to
2480 * enter the LOCAL_BUSY state.
2481 */
2482 l2cap_abort_rx_srej_sent(chan);
2483 }
2484
2485 l2cap_send_ack(chan);
2486
2487 break;
2488 case L2CAP_EV_LOCAL_BUSY_CLEAR:
2489 BT_DBG("Exit LOCAL_BUSY");
2490 clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2491
2492 if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2493 struct l2cap_ctrl local_control;
2494 memset(&local_control, 0, sizeof(local_control));
2495 local_control.sframe = 1;
2496 local_control.super = L2CAP_SUPER_RR;
2497 local_control.poll = 1;
2498 local_control.reqseq = chan->buffer_seq;
Mat Martineaua67d7f62012-05-17 20:53:35 -07002499 l2cap_send_sframe(chan, &local_control);
Mat Martineau608bcc62012-05-17 20:53:32 -07002500
2501 chan->retry_count = 1;
2502 __set_monitor_timer(chan);
2503 chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2504 }
2505 break;
2506 case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2507 l2cap_process_reqseq(chan, control->reqseq);
2508
2509 /* Fall through */
2510
2511 case L2CAP_EV_RECV_FBIT:
2512 if (control && control->final) {
2513 __clear_monitor_timer(chan);
2514 if (chan->unacked_frames > 0)
2515 __set_retrans_timer(chan);
2516 chan->retry_count = 0;
2517 chan->tx_state = L2CAP_TX_STATE_XMIT;
2518 BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2519 }
2520 break;
2521 case L2CAP_EV_EXPLICIT_POLL:
2522 /* Ignore */
2523 break;
2524 case L2CAP_EV_MONITOR_TO:
2525 if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2526 l2cap_send_rr_or_rnr(chan, 1);
2527 __set_monitor_timer(chan);
2528 chan->retry_count++;
2529 } else {
2530 l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
2531 }
2532 break;
2533 default:
2534 break;
2535 }
2536
2537 return err;
2538}
2539
2540static int l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
2541 struct sk_buff_head *skbs, u8 event)
2542{
2543 int err = 0;
2544
2545 BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2546 chan, control, skbs, event, chan->tx_state);
2547
2548 switch (chan->tx_state) {
2549 case L2CAP_TX_STATE_XMIT:
2550 err = l2cap_tx_state_xmit(chan, control, skbs, event);
2551 break;
2552 case L2CAP_TX_STATE_WAIT_F:
2553 err = l2cap_tx_state_wait_f(chan, control, skbs, event);
2554 break;
2555 default:
2556 /* Ignore event */
2557 break;
2558 }
2559
2560 return err;
2561}
2562
Mat Martineau4b51dae92012-05-17 20:53:37 -07002563static void l2cap_pass_to_tx(struct l2cap_chan *chan,
2564 struct l2cap_ctrl *control)
2565{
2566 BT_DBG("chan %p, control %p", chan, control);
2567 l2cap_tx(chan, control, 0, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
2568}
2569
Mat Martineauf80842a2012-05-17 20:53:46 -07002570static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
2571 struct l2cap_ctrl *control)
2572{
2573 BT_DBG("chan %p, control %p", chan, control);
2574 l2cap_tx(chan, control, 0, L2CAP_EV_RECV_FBIT);
2575}
2576
Linus Torvalds1da177e2005-04-16 15:20:36 -07002577/* Copy frame to all raw sockets on that connection */
2578static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
2579{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002580 struct sk_buff *nskb;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002581 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002582
2583 BT_DBG("conn %p", conn);
2584
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002585 mutex_lock(&conn->chan_lock);
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002586
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002587 list_for_each_entry(chan, &conn->chan_l, list) {
Gustavo F. Padovan48454072011-03-25 00:22:30 -03002588 struct sock *sk = chan->sk;
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03002589 if (chan->chan_type != L2CAP_CHAN_RAW)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002590 continue;
2591
2592 /* Don't send frame to the socket it came from */
2593 if (skb->sk == sk)
2594 continue;
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002595 nskb = skb_clone(skb, GFP_ATOMIC);
2596 if (!nskb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002597 continue;
2598
Gustavo F. Padovan23070492011-05-16 17:57:22 -03002599 if (chan->ops->recv(chan->data, nskb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002600 kfree_skb(nskb);
2601 }
Gustavo F. Padovan3d57dc62011-12-17 10:56:45 -02002602
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02002603 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604}
2605
2606/* ---- L2CAP signalling commands ---- */
2607static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
2608 u8 code, u8 ident, u16 dlen, void *data)
2609{
2610 struct sk_buff *skb, **frag;
2611 struct l2cap_cmd_hdr *cmd;
2612 struct l2cap_hdr *lh;
2613 int len, count;
2614
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03002615 BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
2616 conn, code, ident, dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002617
2618 len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
2619 count = min_t(unsigned int, conn->mtu, len);
2620
2621 skb = bt_skb_alloc(count, GFP_ATOMIC);
2622 if (!skb)
2623 return NULL;
2624
2625 lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002626 lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02002627
2628 if (conn->hcon->type == LE_LINK)
2629 lh->cid = cpu_to_le16(L2CAP_CID_LE_SIGNALING);
2630 else
2631 lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002632
2633 cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
2634 cmd->code = code;
2635 cmd->ident = ident;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002636 cmd->len = cpu_to_le16(dlen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002637
2638 if (dlen) {
2639 count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
2640 memcpy(skb_put(skb, count), data, count);
2641 data += count;
2642 }
2643
2644 len -= skb->len;
2645
2646 /* Continuation fragments (no L2CAP header) */
2647 frag = &skb_shinfo(skb)->frag_list;
2648 while (len) {
2649 count = min_t(unsigned int, conn->mtu, len);
2650
2651 *frag = bt_skb_alloc(count, GFP_ATOMIC);
2652 if (!*frag)
2653 goto fail;
2654
2655 memcpy(skb_put(*frag, count), data, count);
2656
2657 len -= count;
2658 data += count;
2659
2660 frag = &(*frag)->next;
2661 }
2662
2663 return skb;
2664
2665fail:
2666 kfree_skb(skb);
2667 return NULL;
2668}
2669
2670static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
2671{
2672 struct l2cap_conf_opt *opt = *ptr;
2673 int len;
2674
2675 len = L2CAP_CONF_OPT_SIZE + opt->len;
2676 *ptr += len;
2677
2678 *type = opt->type;
2679 *olen = opt->len;
2680
2681 switch (opt->len) {
2682 case 1:
2683 *val = *((u8 *) opt->val);
2684 break;
2685
2686 case 2:
steven miaobfaaeb32010-10-16 18:29:47 -04002687 *val = get_unaligned_le16(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002688 break;
2689
2690 case 4:
steven miaobfaaeb32010-10-16 18:29:47 -04002691 *val = get_unaligned_le32(opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002692 break;
2693
2694 default:
2695 *val = (unsigned long) opt->val;
2696 break;
2697 }
2698
2699 BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
2700 return len;
2701}
2702
Linus Torvalds1da177e2005-04-16 15:20:36 -07002703static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
2704{
2705 struct l2cap_conf_opt *opt = *ptr;
2706
2707 BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
2708
2709 opt->type = type;
2710 opt->len = len;
2711
2712 switch (len) {
2713 case 1:
2714 *((u8 *) opt->val) = val;
2715 break;
2716
2717 case 2:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002718 put_unaligned_le16(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002719 break;
2720
2721 case 4:
Gustavo F. Padovan4f8b6912010-10-18 14:25:53 -02002722 put_unaligned_le32(val, opt->val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002723 break;
2724
2725 default:
2726 memcpy(opt->val, (void *) val, len);
2727 break;
2728 }
2729
2730 *ptr += L2CAP_CONF_OPT_SIZE + len;
2731}
2732
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002733static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
2734{
2735 struct l2cap_conf_efs efs;
2736
Szymon Janc1ec918c2011-11-16 09:32:21 +01002737 switch (chan->mode) {
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002738 case L2CAP_MODE_ERTM:
2739 efs.id = chan->local_id;
2740 efs.stype = chan->local_stype;
2741 efs.msdu = cpu_to_le16(chan->local_msdu);
2742 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2743 efs.acc_lat = cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
2744 efs.flush_to = cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO);
2745 break;
2746
2747 case L2CAP_MODE_STREAMING:
2748 efs.id = 1;
2749 efs.stype = L2CAP_SERV_BESTEFFORT;
2750 efs.msdu = cpu_to_le16(chan->local_msdu);
2751 efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
2752 efs.acc_lat = 0;
2753 efs.flush_to = 0;
2754 break;
2755
2756 default:
2757 return;
2758 }
2759
2760 l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
2761 (unsigned long) &efs);
2762}
2763
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002764static void l2cap_ack_timeout(struct work_struct *work)
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002765{
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002766 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
2767 ack_timer.work);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002768
Gustavo F. Padovan2fb9b3d2011-12-22 16:56:05 -02002769 BT_DBG("chan %p", chan);
2770
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002771 l2cap_chan_lock(chan);
2772
Mat Martineau0a0aba42012-05-17 20:53:39 -07002773 l2cap_send_ack(chan);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02002774
2775 l2cap_chan_unlock(chan);
Szymon Janc09bfb2e2012-01-11 10:59:49 +01002776
2777 l2cap_chan_put(chan);
Gustavo F. Padovanc1b4f432010-05-01 16:15:39 -03002778}
2779
Mat Martineau3c588192012-04-11 10:48:42 -07002780static inline int l2cap_ertm_init(struct l2cap_chan *chan)
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002781{
Mat Martineau3c588192012-04-11 10:48:42 -07002782 int err;
2783
Mat Martineau105bdf92012-04-27 16:50:48 -07002784 chan->next_tx_seq = 0;
2785 chan->expected_tx_seq = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002786 chan->expected_ack_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002787 chan->unacked_frames = 0;
Gustavo F. Padovan42e5c802011-03-25 19:58:34 -03002788 chan->buffer_seq = 0;
Gustavo F. Padovan6a026612011-04-01 00:38:50 -03002789 chan->frames_sent = 0;
Mat Martineau105bdf92012-04-27 16:50:48 -07002790 chan->last_acked_seq = 0;
2791 chan->sdu = NULL;
2792 chan->sdu_last_frag = NULL;
2793 chan->sdu_len = 0;
2794
Mat Martineaud34c34f2012-05-14 14:49:27 -07002795 skb_queue_head_init(&chan->tx_q);
2796
Mat Martineau105bdf92012-04-27 16:50:48 -07002797 if (chan->mode != L2CAP_MODE_ERTM)
2798 return 0;
2799
2800 chan->rx_state = L2CAP_RX_STATE_RECV;
2801 chan->tx_state = L2CAP_TX_STATE_XMIT;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002802
Gustavo F. Padovan721c4182011-06-23 19:29:58 -03002803 INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
2804 INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
2805 INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002806
Gustavo F. Padovanf1c67752011-03-25 20:36:10 -03002807 skb_queue_head_init(&chan->srej_q);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03002808
Mat Martineau3c588192012-04-11 10:48:42 -07002809 err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
2810 if (err < 0)
2811 return err;
2812
Mat Martineau9dc9aff2012-05-17 16:20:14 -07002813 err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
2814 if (err < 0)
2815 l2cap_seq_list_free(&chan->srej_list);
2816
2817 return err;
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03002818}
2819
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002820static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
2821{
2822 switch (mode) {
2823 case L2CAP_MODE_STREAMING:
2824 case L2CAP_MODE_ERTM:
2825 if (l2cap_mode_supported(mode, remote_feat_mask))
2826 return mode;
2827 /* fall through */
2828 default:
2829 return L2CAP_MODE_BASIC;
2830 }
2831}
2832
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002833static inline bool __l2cap_ews_supported(struct l2cap_chan *chan)
2834{
2835 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW;
2836}
2837
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002838static inline bool __l2cap_efs_supported(struct l2cap_chan *chan)
2839{
2840 return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW;
2841}
2842
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002843static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
2844{
2845 if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002846 __l2cap_ews_supported(chan)) {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002847 /* use extended control field */
2848 set_bit(FLAG_EXT_CTRL, &chan->flags);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002849 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
2850 } else {
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002851 chan->tx_win = min_t(u16, chan->tx_win,
2852 L2CAP_DEFAULT_TX_WINDOW);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03002853 chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
2854 }
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002855}
2856
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03002857static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002858{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002859 struct l2cap_conf_req *req = data;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002860 struct l2cap_conf_rfc rfc = { .mode = chan->mode };
Linus Torvalds1da177e2005-04-16 15:20:36 -07002861 void *ptr = req->data;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002862 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002863
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03002864 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002865
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002866 if (chan->num_conf_req || chan->num_conf_rsp)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002867 goto done;
2868
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002869 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002870 case L2CAP_MODE_STREAMING:
2871 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002872 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002873 break;
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03002874
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002875 if (__l2cap_efs_supported(chan))
2876 set_bit(FLAG_EFS_ENABLE, &chan->flags);
2877
Gustavo F. Padovan2ba13ed2010-06-09 16:39:05 -03002878 /* fall through */
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002879 default:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002880 chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002881 break;
2882 }
2883
2884done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002885 if (chan->imtu != L2CAP_DEFAULT_MTU)
2886 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovan7990681c2011-01-24 16:01:43 -02002887
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03002888 switch (chan->mode) {
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002889 case L2CAP_MODE_BASIC:
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002890 if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
2891 !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002892 break;
2893
Gustavo F. Padovan62547752010-06-08 20:05:31 -03002894 rfc.mode = L2CAP_MODE_BASIC;
2895 rfc.txwin_size = 0;
2896 rfc.max_transmit = 0;
2897 rfc.retrans_timeout = 0;
2898 rfc.monitor_timeout = 0;
2899 rfc.max_pdu_size = 0;
2900
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002901 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2902 (unsigned long) &rfc);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002903 break;
2904
2905 case L2CAP_MODE_ERTM:
2906 rfc.mode = L2CAP_MODE_ERTM;
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002907 rfc.max_transmit = chan->max_tx;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002908 rfc.retrans_timeout = 0;
2909 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002910
2911 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
2912 L2CAP_EXT_HDR_SIZE -
2913 L2CAP_SDULEN_SIZE -
2914 L2CAP_FCS_SIZE);
2915 rfc.max_pdu_size = cpu_to_le16(size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002916
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002917 l2cap_txwin_setup(chan);
2918
2919 rfc.txwin_size = min_t(u16, chan->tx_win,
2920 L2CAP_DEFAULT_TX_WINDOW);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002921
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002922 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2923 (unsigned long) &rfc);
2924
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002925 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2926 l2cap_add_opt_efs(&ptr, chan);
2927
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002928 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002929 break;
2930
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002931 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002932 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002933 chan->fcs = L2CAP_FCS_NONE;
2934 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002935 }
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03002936
2937 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
2938 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
2939 chan->tx_win);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03002940 break;
2941
2942 case L2CAP_MODE_STREAMING:
2943 rfc.mode = L2CAP_MODE_STREAMING;
2944 rfc.txwin_size = 0;
2945 rfc.max_transmit = 0;
2946 rfc.retrans_timeout = 0;
2947 rfc.monitor_timeout = 0;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002948
2949 size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
2950 L2CAP_EXT_HDR_SIZE -
2951 L2CAP_SDULEN_SIZE -
2952 L2CAP_FCS_SIZE);
2953 rfc.max_pdu_size = cpu_to_le16(size);
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002954
Gustavo F. Padovan63406502010-08-03 23:49:29 -03002955 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2956 (unsigned long) &rfc);
2957
Andrei Emeltchenkof89cef02011-10-13 16:18:55 +03002958 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
2959 l2cap_add_opt_efs(&ptr, chan);
2960
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03002961 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002962 break;
2963
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002964 if (chan->fcs == L2CAP_FCS_NONE ||
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03002965 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03002966 chan->fcs = L2CAP_FCS_NONE;
2967 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03002968 }
Marcel Holtmann65c7c492009-05-02 23:07:53 -07002969 break;
2970 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002971
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03002972 req->dcid = cpu_to_le16(chan->dcid);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07002973 req->flags = cpu_to_le16(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002974
2975 return ptr - data;
2976}
2977
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002978static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979{
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002980 struct l2cap_conf_rsp *rsp = data;
2981 void *ptr = rsp->data;
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002982 void *req = chan->conf_req;
2983 int len = chan->conf_len;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002984 int type, hint, olen;
2985 unsigned long val;
Marcel Holtmann6464f352007-10-20 13:39:51 +02002986 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03002987 struct l2cap_conf_efs efs;
2988 u8 remote_efs = 0;
Marcel Holtmann861d6882007-10-20 13:37:06 +02002989 u16 mtu = L2CAP_DEFAULT_MTU;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002990 u16 result = L2CAP_CONF_SUCCESS;
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03002991 u16 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002992
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03002993 BT_DBG("chan %p", chan);
Marcel Holtmann820ae1b2006-11-18 22:15:00 +01002994
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02002995 while (len >= L2CAP_CONF_OPT_SIZE) {
2996 len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002997
Gustavo F. Padovan589d2742009-04-20 01:31:07 -03002998 hint = type & L2CAP_CONF_HINT;
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07002999 type &= L2CAP_CONF_MASK;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003000
3001 switch (type) {
3002 case L2CAP_CONF_MTU:
Marcel Holtmann861d6882007-10-20 13:37:06 +02003003 mtu = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003004 break;
3005
3006 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003007 chan->flush_to = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003008 break;
3009
3010 case L2CAP_CONF_QOS:
3011 break;
3012
Marcel Holtmann6464f352007-10-20 13:39:51 +02003013 case L2CAP_CONF_RFC:
3014 if (olen == sizeof(rfc))
3015 memcpy(&rfc, (void *) val, olen);
3016 break;
3017
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003018 case L2CAP_CONF_FCS:
3019 if (val == L2CAP_FCS_NONE)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003020 set_bit(CONF_NO_FCS_RECV, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003021 break;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003022
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003023 case L2CAP_CONF_EFS:
3024 remote_efs = 1;
3025 if (olen == sizeof(efs))
3026 memcpy(&efs, (void *) val, olen);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003027 break;
3028
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003029 case L2CAP_CONF_EWS:
3030 if (!enable_hs)
3031 return -ECONNREFUSED;
3032
3033 set_bit(FLAG_EXT_CTRL, &chan->flags);
3034 set_bit(CONF_EWS_RECV, &chan->conf_state);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03003035 chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003036 chan->remote_tx_win = val;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003037 break;
3038
3039 default:
3040 if (hint)
3041 break;
3042
3043 result = L2CAP_CONF_UNKNOWN;
3044 *((u8 *) ptr++) = type;
3045 break;
3046 }
3047 }
3048
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003049 if (chan->num_conf_rsp || chan->num_conf_req > 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003050 goto done;
3051
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003052 switch (chan->mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003053 case L2CAP_MODE_STREAMING:
3054 case L2CAP_MODE_ERTM:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003055 if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003056 chan->mode = l2cap_select_mode(rfc.mode,
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003057 chan->conn->feat_mask);
Gustavo F. Padovan85eb53c2010-06-03 18:43:28 -03003058 break;
3059 }
3060
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003061 if (remote_efs) {
3062 if (__l2cap_efs_supported(chan))
3063 set_bit(FLAG_EFS_ENABLE, &chan->flags);
3064 else
3065 return -ECONNREFUSED;
3066 }
3067
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003068 if (chan->mode != rfc.mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003069 return -ECONNREFUSED;
Gustavo F. Padovan742e5192010-06-08 19:09:48 -03003070
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003071 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003072 }
3073
3074done:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003075 if (chan->mode != rfc.mode) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003076 result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003077 rfc.mode = chan->mode;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003078
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003079 if (chan->num_conf_rsp == 1)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003080 return -ECONNREFUSED;
3081
3082 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3083 sizeof(rfc), (unsigned long) &rfc);
3084 }
3085
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003086 if (result == L2CAP_CONF_SUCCESS) {
3087 /* Configure output options and let the other side know
3088 * which ones we don't like. */
3089
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003090 if (mtu < L2CAP_DEFAULT_MIN_MTU)
3091 result = L2CAP_CONF_UNACCEPT;
3092 else {
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003093 chan->omtu = mtu;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003094 set_bit(CONF_MTU_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003095 }
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003096 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003097
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003098 if (remote_efs) {
3099 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
3100 efs.stype != L2CAP_SERV_NOTRAFIC &&
3101 efs.stype != chan->local_stype) {
3102
3103 result = L2CAP_CONF_UNACCEPT;
3104
3105 if (chan->num_conf_req >= 1)
3106 return -ECONNREFUSED;
3107
3108 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003109 sizeof(efs),
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003110 (unsigned long) &efs);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003111 } else {
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003112 /* Send PENDING Conf Rsp */
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003113 result = L2CAP_CONF_PENDING;
3114 set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003115 }
3116 }
3117
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003118 switch (rfc.mode) {
3119 case L2CAP_MODE_BASIC:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003120 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003121 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003122 break;
3123
3124 case L2CAP_MODE_ERTM:
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003125 if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
3126 chan->remote_tx_win = rfc.txwin_size;
3127 else
3128 rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
3129
Gustavo F. Padovan2c03a7a2011-03-25 20:15:28 -03003130 chan->remote_max_tx = rfc.max_transmit;
Mat Martineau86b1b262010-08-05 15:54:22 -07003131
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003132 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
3133 chan->conn->mtu -
3134 L2CAP_EXT_HDR_SIZE -
3135 L2CAP_SDULEN_SIZE -
3136 L2CAP_FCS_SIZE);
3137 rfc.max_pdu_size = cpu_to_le16(size);
3138 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003139
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003140 rfc.retrans_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003141 __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
Gustavo F. Padovan10467e92010-05-01 16:15:40 -03003142 rfc.monitor_timeout =
Andrei Emeltchenko4fd21a82012-03-12 12:13:10 +02003143 __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003144
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003145 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003146
3147 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3148 sizeof(rfc), (unsigned long) &rfc);
3149
Andrei Emeltchenko42dceae2011-10-17 14:35:30 +03003150 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3151 chan->remote_id = efs.id;
3152 chan->remote_stype = efs.stype;
3153 chan->remote_msdu = le16_to_cpu(efs.msdu);
3154 chan->remote_flush_to =
3155 le32_to_cpu(efs.flush_to);
3156 chan->remote_acc_lat =
3157 le32_to_cpu(efs.acc_lat);
3158 chan->remote_sdu_itime =
3159 le32_to_cpu(efs.sdu_itime);
3160 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
3161 sizeof(efs), (unsigned long) &efs);
3162 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003163 break;
3164
3165 case L2CAP_MODE_STREAMING:
Andrei Emeltchenkoc8f79162011-10-17 12:19:59 +03003166 size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
3167 chan->conn->mtu -
3168 L2CAP_EXT_HDR_SIZE -
3169 L2CAP_SDULEN_SIZE -
3170 L2CAP_FCS_SIZE);
3171 rfc.max_pdu_size = cpu_to_le16(size);
3172 chan->remote_mps = size;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003173
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003174 set_bit(CONF_MODE_DONE, &chan->conf_state);
Gustavo F. Padovan68ae6632009-10-17 21:41:01 -03003175
3176 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3177 sizeof(rfc), (unsigned long) &rfc);
3178
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003179 break;
3180
3181 default:
Marcel Holtmann6464f352007-10-20 13:39:51 +02003182 result = L2CAP_CONF_UNACCEPT;
3183
3184 memset(&rfc, 0, sizeof(rfc));
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003185 rfc.mode = chan->mode;
Marcel Holtmann6464f352007-10-20 13:39:51 +02003186 }
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003187
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003188 if (result == L2CAP_CONF_SUCCESS)
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003189 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003190 }
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003191 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003192 rsp->result = cpu_to_le16(result);
3193 rsp->flags = cpu_to_le16(0x0000);
3194
3195 return ptr - data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003196}
3197
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003198static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, void *data, u16 *result)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003199{
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003200 struct l2cap_conf_req *req = data;
3201 void *ptr = req->data;
3202 int type, olen;
3203 unsigned long val;
Mat Martineau36e999a2011-12-08 17:23:21 -08003204 struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003205 struct l2cap_conf_efs efs;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003206
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003207 BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003208
3209 while (len >= L2CAP_CONF_OPT_SIZE) {
3210 len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
3211
3212 switch (type) {
3213 case L2CAP_CONF_MTU:
3214 if (val < L2CAP_DEFAULT_MIN_MTU) {
3215 *result = L2CAP_CONF_UNACCEPT;
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003216 chan->imtu = L2CAP_DEFAULT_MIN_MTU;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003217 } else
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003218 chan->imtu = val;
3219 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003220 break;
3221
3222 case L2CAP_CONF_FLUSH_TO:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003223 chan->flush_to = val;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003224 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003225 2, chan->flush_to);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003226 break;
3227
3228 case L2CAP_CONF_RFC:
3229 if (olen == sizeof(rfc))
3230 memcpy(&rfc, (void *)val, olen);
3231
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003232 if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003233 rfc.mode != chan->mode)
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003234 return -ECONNREFUSED;
3235
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003236 chan->fcs = 0;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003237
3238 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3239 sizeof(rfc), (unsigned long) &rfc);
3240 break;
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003241
3242 case L2CAP_CONF_EWS:
3243 chan->tx_win = min_t(u16, val,
3244 L2CAP_DEFAULT_EXT_WINDOW);
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003245 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
3246 chan->tx_win);
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003247 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003248
3249 case L2CAP_CONF_EFS:
3250 if (olen == sizeof(efs))
3251 memcpy(&efs, (void *)val, olen);
3252
3253 if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
3254 efs.stype != L2CAP_SERV_NOTRAFIC &&
3255 efs.stype != chan->local_stype)
3256 return -ECONNREFUSED;
3257
3258 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
3259 sizeof(efs), (unsigned long) &efs);
3260 break;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003261 }
3262 }
3263
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003264 if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003265 return -ECONNREFUSED;
3266
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003267 chan->mode = rfc.mode;
Gustavo F. Padovan6c2ea7a2010-06-08 20:08:49 -03003268
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003269 if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003270 switch (rfc.mode) {
3271 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003272 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3273 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3274 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003275
3276 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
3277 chan->local_msdu = le16_to_cpu(efs.msdu);
3278 chan->local_sdu_itime =
3279 le32_to_cpu(efs.sdu_itime);
3280 chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
3281 chan->local_flush_to =
3282 le32_to_cpu(efs.flush_to);
3283 }
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003284 break;
Andrei Emeltchenko66af7aa2011-11-07 14:20:33 +02003285
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003286 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003287 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003288 }
3289 }
3290
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003291 req->dcid = cpu_to_le16(chan->dcid);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003292 req->flags = cpu_to_le16(0x0000);
3293
3294 return ptr - data;
3295}
3296
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003297static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data, u16 result, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003298{
3299 struct l2cap_conf_rsp *rsp = data;
3300 void *ptr = rsp->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003301
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003302 BT_DBG("chan %p", chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003303
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003304 rsp->scid = cpu_to_le16(chan->dcid);
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003305 rsp->result = cpu_to_le16(result);
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003306 rsp->flags = cpu_to_le16(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003307
3308 return ptr - data;
3309}
3310
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003311void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003312{
3313 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03003314 struct l2cap_conn *conn = chan->conn;
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003315 u8 buf[128];
3316
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003317 rsp.scid = cpu_to_le16(chan->dcid);
3318 rsp.dcid = cpu_to_le16(chan->scid);
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003319 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
3320 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
3321 l2cap_send_cmd(conn, chan->ident,
3322 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
3323
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003324 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003325 return;
3326
Gustavo F. Padovan710f9b02011-03-25 14:30:37 -03003327 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3328 l2cap_build_conf_req(chan, buf), buf);
3329 chan->num_conf_req++;
3330}
3331
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003332static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003333{
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003334 int type, olen;
3335 unsigned long val;
3336 struct l2cap_conf_rfc rfc;
3337
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
3346 switch (type) {
3347 case L2CAP_CONF_RFC:
3348 if (olen == sizeof(rfc))
3349 memcpy(&rfc, (void *)val, olen);
3350 goto done;
3351 }
3352 }
3353
Mat Martineau36e999a2011-12-08 17:23:21 -08003354 /* Use sane default values in case a misbehaving remote device
3355 * did not send an RFC option.
3356 */
3357 rfc.mode = chan->mode;
3358 rfc.retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3359 rfc.monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
3360 rfc.max_pdu_size = cpu_to_le16(chan->imtu);
3361
3362 BT_ERR("Expected RFC option was not found, using defaults");
3363
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003364done:
3365 switch (rfc.mode) {
3366 case L2CAP_MODE_ERTM:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003367 chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
3368 chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
3369 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003370 break;
3371 case L2CAP_MODE_STREAMING:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003372 chan->mps = le16_to_cpu(rfc.max_pdu_size);
Gustavo F. Padovan7b1c0042010-05-01 16:15:39 -03003373 }
3374}
3375
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003376static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3377{
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003378 struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003379
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003380 if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003381 return 0;
3382
3383 if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
3384 cmd->ident == conn->info_ident) {
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003385 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann984947d2009-02-06 23:35:19 +01003386
3387 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003388 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01003389
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003390 l2cap_conn_start(conn);
3391 }
3392
3393 return 0;
3394}
3395
Linus Torvalds1da177e2005-04-16 15:20:36 -07003396static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3397{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003398 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3399 struct l2cap_conn_rsp rsp;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003400 struct l2cap_chan *chan = NULL, *pchan;
Nathan Holsteind793fe82010-10-15 11:54:02 -04003401 struct sock *parent, *sk = NULL;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003402 int result, status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003403
3404 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003405 __le16 psm = req->psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003406
Andrei Emeltchenko097db762012-03-09 14:16:17 +02003407 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003408
3409 /* Check if we have socket listening on psm */
Ido Yarivc2287682012-04-20 15:46:07 -03003410 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003411 if (!pchan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003412 result = L2CAP_CR_BAD_PSM;
3413 goto sendresp;
3414 }
3415
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03003416 parent = pchan->sk;
3417
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003418 mutex_lock(&conn->chan_lock);
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003419 lock_sock(parent);
Gustavo F. Padovane0f0cb52010-11-01 18:43:53 +00003420
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003421 /* Check if the ACL is secure enough (if not SDP) */
3422 if (psm != cpu_to_le16(0x0001) &&
3423 !hci_conn_check_link_mode(conn->hcon)) {
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003424 conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +02003425 result = L2CAP_CR_SEC_BLOCK;
3426 goto response;
3427 }
3428
Linus Torvalds1da177e2005-04-16 15:20:36 -07003429 result = L2CAP_CR_NO_MEM;
3430
3431 /* Check for backlog size */
3432 if (sk_acceptq_is_full(parent)) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003433 BT_DBG("backlog full %d", parent->sk_ack_backlog);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003434 goto response;
3435 }
3436
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003437 chan = pchan->ops->new_connection(pchan->data);
3438 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003439 goto response;
3440
Gustavo F. Padovan80808e42011-05-16 17:24:37 -03003441 sk = chan->sk;
3442
Linus Torvalds1da177e2005-04-16 15:20:36 -07003443 /* Check if we already have channel with that dcid */
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003444 if (__l2cap_get_chan_by_dcid(conn, scid)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003445 sock_set_flag(sk, SOCK_ZAPPED);
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -03003446 chan->ops->close(chan->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003447 goto response;
3448 }
3449
3450 hci_conn_hold(conn->hcon);
3451
Linus Torvalds1da177e2005-04-16 15:20:36 -07003452 bacpy(&bt_sk(sk)->src, conn->src);
3453 bacpy(&bt_sk(sk)->dst, conn->dst);
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003454 chan->psm = psm;
3455 chan->dcid = scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003456
Gustavo F. Padovand1010242011-03-25 00:39:48 -03003457 bt_accept_enqueue(parent, sk);
3458
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003459 __l2cap_chan_add(conn, chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003460
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003461 dcid = chan->scid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003462
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03003463 __set_chan_timer(chan, sk->sk_sndtimeo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003464
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003465 chan->ident = cmd->ident;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003466
Marcel Holtmann984947d2009-02-06 23:35:19 +01003467 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
Gustavo F. Padovand45fc422011-11-05 19:54:24 -02003468 if (l2cap_chan_check_security(chan)) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03003469 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003470 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003471 result = L2CAP_CR_PEND;
3472 status = L2CAP_CS_AUTHOR_PEND;
3473 parent->sk_data_ready(parent, 0);
3474 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003475 __l2cap_state_change(chan, BT_CONFIG);
Marcel Holtmannf66dc812009-01-15 21:57:00 +01003476 result = L2CAP_CR_SUCCESS;
3477 status = L2CAP_CS_NO_INFO;
3478 }
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003479 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003480 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003481 result = L2CAP_CR_PEND;
3482 status = L2CAP_CS_AUTHEN_PEND;
3483 }
3484 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02003485 __l2cap_state_change(chan, BT_CONNECT2);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003486 result = L2CAP_CR_PEND;
3487 status = L2CAP_CS_NO_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003488 }
3489
Linus Torvalds1da177e2005-04-16 15:20:36 -07003490response:
Gustavo F. Padovanaa2ac882011-06-24 01:53:01 -03003491 release_sock(parent);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003492 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003493
3494sendresp:
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -07003495 rsp.scid = cpu_to_le16(scid);
3496 rsp.dcid = cpu_to_le16(dcid);
3497 rsp.result = cpu_to_le16(result);
3498 rsp.status = cpu_to_le16(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003499 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003500
3501 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
3502 struct l2cap_info_req info;
3503 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3504
3505 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
3506 conn->info_ident = l2cap_get_ident(conn);
3507
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003508 schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003509
3510 l2cap_send_cmd(conn, conn->info_ident,
3511 L2CAP_INFO_REQ, sizeof(info), &info);
3512 }
3513
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003514 if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003515 result == L2CAP_CR_SUCCESS) {
3516 u8 buf[128];
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003517 set_bit(CONF_REQ_SENT, &chan->conf_state);
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003518 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003519 l2cap_build_conf_req(chan, buf), buf);
3520 chan->num_conf_req++;
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003521 }
3522
Linus Torvalds1da177e2005-04-16 15:20:36 -07003523 return 0;
3524}
3525
3526static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3527{
3528 struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
3529 u16 scid, dcid, result, status;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003530 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003531 u8 req[128];
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003532 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003533
3534 scid = __le16_to_cpu(rsp->scid);
3535 dcid = __le16_to_cpu(rsp->dcid);
3536 result = __le16_to_cpu(rsp->result);
3537 status = __le16_to_cpu(rsp->status);
3538
Andrei Emeltchenko1b009c92012-02-21 12:54:54 +02003539 BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x",
3540 dcid, scid, result, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003541
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003542 mutex_lock(&conn->chan_lock);
3543
Linus Torvalds1da177e2005-04-16 15:20:36 -07003544 if (scid) {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003545 chan = __l2cap_get_chan_by_scid(conn, scid);
3546 if (!chan) {
3547 err = -EFAULT;
3548 goto unlock;
3549 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003550 } else {
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003551 chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
3552 if (!chan) {
3553 err = -EFAULT;
3554 goto unlock;
3555 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003556 }
3557
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003558 err = 0;
3559
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003560 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003561
Linus Torvalds1da177e2005-04-16 15:20:36 -07003562 switch (result) {
3563 case L2CAP_CR_SUCCESS:
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003564 l2cap_state_change(chan, BT_CONFIG);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03003565 chan->ident = 0;
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003566 chan->dcid = dcid;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003567 clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01003568
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003569 if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
Gustavo F. Padovane9aeb2d2010-07-08 20:08:18 -03003570 break;
3571
Linus Torvalds1da177e2005-04-16 15:20:36 -07003572 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003573 l2cap_build_conf_req(chan, req), req);
3574 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003575 break;
3576
3577 case L2CAP_CR_PEND:
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003578 set_bit(CONF_CONNECT_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003579 break;
3580
3581 default:
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003582 l2cap_chan_del(chan, ECONNREFUSED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003583 break;
3584 }
3585
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003586 l2cap_chan_unlock(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003587
3588unlock:
3589 mutex_unlock(&conn->chan_lock);
3590
3591 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003592}
3593
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003594static inline void set_default_fcs(struct l2cap_chan *chan)
Mat Martineau8c462b62010-08-24 15:35:42 -07003595{
3596 /* FCS is enabled only in ERTM or streaming mode, if one or both
3597 * sides request it.
3598 */
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03003599 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003600 chan->fcs = L2CAP_FCS_NONE;
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003601 else if (!test_bit(CONF_NO_FCS_RECV, &chan->conf_state))
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003602 chan->fcs = L2CAP_FCS_CRC16;
Mat Martineau8c462b62010-08-24 15:35:42 -07003603}
3604
Al Viro88219a02007-07-29 00:17:25 -07003605static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003606{
3607 struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
3608 u16 dcid, flags;
3609 u8 rsp[64];
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003610 struct l2cap_chan *chan;
Mat Martineau3c588192012-04-11 10:48:42 -07003611 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003612
3613 dcid = __le16_to_cpu(req->dcid);
3614 flags = __le16_to_cpu(req->flags);
3615
3616 BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
3617
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003618 chan = l2cap_get_chan_by_scid(conn, dcid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003619 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003620 return -ENOENT;
3621
David S. Miller033b1142011-07-21 13:38:42 -07003622 if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003623 struct l2cap_cmd_rej_cid rej;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003624
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03003625 rej.reason = cpu_to_le16(L2CAP_REJ_INVALID_CID);
3626 rej.scid = cpu_to_le16(chan->scid);
3627 rej.dcid = cpu_to_le16(chan->dcid);
3628
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003629 l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
3630 sizeof(rej), &rej);
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003631 goto unlock;
Gustavo F. Padovandf6bd742010-06-14 02:26:15 -03003632 }
Marcel Holtmann354f60a2006-11-18 22:15:20 +01003633
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003634 /* Reject if config buffer is too small. */
Al Viro88219a02007-07-29 00:17:25 -07003635 len = cmd_len - sizeof(*req);
Dan Rosenberg7ac28812011-06-24 08:38:05 -04003636 if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003637 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003638 l2cap_build_conf_rsp(chan, rsp,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003639 L2CAP_CONF_REJECT, flags), rsp);
3640 goto unlock;
3641 }
3642
3643 /* Store config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003644 memcpy(chan->conf_req + chan->conf_len, req->data, len);
3645 chan->conf_len += len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003646
3647 if (flags & 0x0001) {
3648 /* Incomplete config. Send empty response. */
3649 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003650 l2cap_build_conf_rsp(chan, rsp,
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003651 L2CAP_CONF_SUCCESS, 0x0001), rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003652 goto unlock;
3653 }
3654
3655 /* Complete config. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003656 len = l2cap_parse_conf_req(chan, rsp);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003657 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003658 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003659 goto unlock;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003660 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003661
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003662 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003663 chan->num_conf_rsp++;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003664
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003665 /* Reset config buffer. */
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003666 chan->conf_len = 0;
Marcel Holtmann5dee9e72007-05-24 14:27:19 +02003667
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003668 if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
Marcel Holtmann876d9482007-10-20 13:35:42 +02003669 goto unlock;
3670
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003671 if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003672 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003673
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003674 l2cap_state_change(chan, BT_CONNECTED);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003675
Mat Martineau105bdf92012-04-27 16:50:48 -07003676 if (chan->mode == L2CAP_MODE_ERTM ||
3677 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003678 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003679
Mat Martineau3c588192012-04-11 10:48:42 -07003680 if (err < 0)
3681 l2cap_send_disconn_req(chan->conn, chan, -err);
3682 else
3683 l2cap_chan_ready(chan);
3684
Marcel Holtmann876d9482007-10-20 13:35:42 +02003685 goto unlock;
3686 }
3687
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003688 if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
Marcel Holtmann79d554a2008-07-14 20:13:44 +02003689 u8 buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003690 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003691 l2cap_build_conf_req(chan, buf), buf);
3692 chan->num_conf_req++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003693 }
3694
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003695 /* Got Conf Rsp PENDING from remote side and asume we sent
3696 Conf Rsp PENDING in the code above */
3697 if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
3698 test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3699
3700 /* check compatibility */
3701
3702 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3703 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3704
3705 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003706 l2cap_build_conf_rsp(chan, rsp,
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003707 L2CAP_CONF_SUCCESS, 0x0000), rsp);
3708 }
3709
Linus Torvalds1da177e2005-04-16 15:20:36 -07003710unlock:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003711 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003712 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003713}
3714
3715static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3716{
3717 struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
3718 u16 scid, flags, result;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003719 struct l2cap_chan *chan;
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003720 int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
Mat Martineau3c588192012-04-11 10:48:42 -07003721 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003722
3723 scid = __le16_to_cpu(rsp->scid);
3724 flags = __le16_to_cpu(rsp->flags);
3725 result = __le16_to_cpu(rsp->result);
3726
Andrei Emeltchenko61386cb2012-03-12 12:13:07 +02003727 BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
3728 result, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003729
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03003730 chan = l2cap_get_chan_by_scid(conn, scid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003731 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003732 return 0;
3733
3734 switch (result) {
3735 case L2CAP_CONF_SUCCESS:
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003736 l2cap_conf_rfc_get(chan, rsp->data, len);
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003737 clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003738 break;
3739
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003740 case L2CAP_CONF_PENDING:
3741 set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
3742
3743 if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
3744 char buf[64];
3745
3746 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3747 buf, &result);
3748 if (len < 0) {
3749 l2cap_send_disconn_req(conn, chan, ECONNRESET);
3750 goto done;
3751 }
3752
3753 /* check compatibility */
3754
3755 clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
3756 set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
3757
3758 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
Gustavo F. Padovan3e6b3b92011-11-01 14:06:23 -02003759 l2cap_build_conf_rsp(chan, buf,
Andrei Emeltchenko0e8b2072011-10-17 14:35:32 +03003760 L2CAP_CONF_SUCCESS, 0x0000), buf);
3761 }
3762 goto done;
3763
Linus Torvalds1da177e2005-04-16 15:20:36 -07003764 case L2CAP_CONF_UNACCEPT:
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003765 if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003766 char req[64];
3767
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003768 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003769 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Andrei Emeltchenkoc2c77ec2010-03-19 10:26:28 +02003770 goto done;
3771 }
3772
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003773 /* throw out any old stored conf requests */
3774 result = L2CAP_CONF_SUCCESS;
Gustavo F. Padovanb4450032011-04-12 18:15:09 -03003775 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3776 req, &result);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003777 if (len < 0) {
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003778 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003779 goto done;
3780 }
3781
3782 l2cap_send_cmd(conn, l2cap_get_ident(conn),
3783 L2CAP_CONF_REQ, len, req);
Gustavo F. Padovan73ffa902011-03-25 14:16:54 -03003784 chan->num_conf_req++;
Gustavo F. Padovanf2fcfcd2009-07-04 15:06:24 -03003785 if (result != L2CAP_CONF_SUCCESS)
3786 goto done;
3787 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003788 }
3789
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09003790 default:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003791 l2cap_chan_set_err(chan, ECONNRESET);
Andrei Emeltchenko2e0052e2012-02-21 12:54:58 +02003792
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08003793 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
Gustavo F. Padovane92c8e72011-04-01 00:53:45 -03003794 l2cap_send_disconn_req(conn, chan, ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003795 goto done;
3796 }
3797
3798 if (flags & 0x01)
3799 goto done;
3800
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003801 set_bit(CONF_INPUT_DONE, &chan->conf_state);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003802
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03003803 if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03003804 set_default_fcs(chan);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003805
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03003806 l2cap_state_change(chan, BT_CONNECTED);
Mat Martineau105bdf92012-04-27 16:50:48 -07003807 if (chan->mode == L2CAP_MODE_ERTM ||
3808 chan->mode == L2CAP_MODE_STREAMING)
Mat Martineau3c588192012-04-11 10:48:42 -07003809 err = l2cap_ertm_init(chan);
Gustavo F. Padovan0565c1c2009-10-03 02:34:36 -03003810
Mat Martineau3c588192012-04-11 10:48:42 -07003811 if (err < 0)
3812 l2cap_send_disconn_req(chan->conn, chan, -err);
3813 else
3814 l2cap_chan_ready(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003815 }
3816
3817done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003818 l2cap_chan_unlock(chan);
Mat Martineau3c588192012-04-11 10:48:42 -07003819 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003820}
3821
3822static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3823{
3824 struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
3825 struct l2cap_disconn_rsp rsp;
3826 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003827 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003828 struct sock *sk;
3829
3830 scid = __le16_to_cpu(req->scid);
3831 dcid = __le16_to_cpu(req->dcid);
3832
3833 BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
3834
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003835 mutex_lock(&conn->chan_lock);
3836
3837 chan = __l2cap_get_chan_by_scid(conn, dcid);
3838 if (!chan) {
3839 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003840 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003841 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003842
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003843 l2cap_chan_lock(chan);
3844
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003845 sk = chan->sk;
3846
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03003847 rsp.dcid = cpu_to_le16(chan->scid);
3848 rsp.scid = cpu_to_le16(chan->dcid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003849 l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
3850
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003851 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003852 sk->sk_shutdown = SHUTDOWN_MASK;
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003853 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003854
Mat Martineau61d6ef32012-04-27 16:50:50 -07003855 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003856 l2cap_chan_del(chan, ECONNRESET);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003857
3858 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003859
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -03003860 chan->ops->close(chan->data);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003861 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003862
3863 mutex_unlock(&conn->chan_lock);
3864
Linus Torvalds1da177e2005-04-16 15:20:36 -07003865 return 0;
3866}
3867
3868static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3869{
3870 struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
3871 u16 dcid, scid;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003872 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003873
3874 scid = __le16_to_cpu(rsp->scid);
3875 dcid = __le16_to_cpu(rsp->dcid);
3876
3877 BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
3878
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003879 mutex_lock(&conn->chan_lock);
3880
3881 chan = __l2cap_get_chan_by_scid(conn, scid);
3882 if (!chan) {
3883 mutex_unlock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003884 return 0;
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003885 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003886
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003887 l2cap_chan_lock(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003888
Mat Martineau61d6ef32012-04-27 16:50:50 -07003889 l2cap_chan_hold(chan);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03003890 l2cap_chan_del(chan, 0);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02003891
3892 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003893
Gustavo F. Padovanba3bd0e2011-05-16 18:23:24 -03003894 chan->ops->close(chan->data);
Mat Martineau61d6ef32012-04-27 16:50:50 -07003895 l2cap_chan_put(chan);
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02003896
3897 mutex_unlock(&conn->chan_lock);
3898
Linus Torvalds1da177e2005-04-16 15:20:36 -07003899 return 0;
3900}
3901
3902static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3903{
3904 struct l2cap_info_req *req = (struct l2cap_info_req *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003905 u16 type;
3906
3907 type = __le16_to_cpu(req->type);
3908
3909 BT_DBG("type 0x%4.4x", type);
3910
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003911 if (type == L2CAP_IT_FEAT_MASK) {
3912 u8 buf[8];
Marcel Holtmann44dd46d2009-05-02 19:09:01 -07003913 u32 feat_mask = l2cap_feat_mask;
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003914 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
3915 rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
3916 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03003917 if (!disable_ertm)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03003918 feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
3919 | L2CAP_FEAT_FCS;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003920 if (enable_hs)
Andrei Emeltchenko6327eb92011-10-11 13:37:42 +03003921 feat_mask |= L2CAP_FEAT_EXT_FLOW
3922 | L2CAP_FEAT_EXT_WINDOW;
Andrei Emeltchenkoa5fd6f32011-09-16 16:26:32 +03003923
Gustavo F. Padovan1b7bf4e2009-08-24 00:45:20 -03003924 put_unaligned_le32(feat_mask, rsp->data);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003925 l2cap_send_cmd(conn, cmd->ident,
3926 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003927 } else if (type == L2CAP_IT_FIXED_CHAN) {
3928 u8 buf[12];
3929 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
Mat Martineau50a147c2011-11-02 16:18:34 -07003930
3931 if (enable_hs)
3932 l2cap_fixed_chan[0] |= L2CAP_FC_A2MP;
3933 else
3934 l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP;
3935
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003936 rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3937 rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
Andrei Emeltchenkoc6337ea2011-10-20 17:02:44 +03003938 memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan));
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003939 l2cap_send_cmd(conn, cmd->ident,
3940 L2CAP_INFO_RSP, sizeof(buf), buf);
Marcel Holtmannf0709e02007-10-20 13:38:51 +02003941 } else {
3942 struct l2cap_info_rsp rsp;
3943 rsp.type = cpu_to_le16(type);
3944 rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
3945 l2cap_send_cmd(conn, cmd->ident,
3946 L2CAP_INFO_RSP, sizeof(rsp), &rsp);
3947 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003948
3949 return 0;
3950}
3951
3952static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
3953{
3954 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
3955 u16 type, result;
3956
3957 type = __le16_to_cpu(rsp->type);
3958 result = __le16_to_cpu(rsp->result);
3959
3960 BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
3961
Andrei Emeltchenkoe90165b2011-03-25 11:31:41 +02003962 /* L2CAP Info req/rsp are unbound to channels, add extra checks */
3963 if (cmd->ident != conn->info_ident ||
3964 conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
3965 return 0;
3966
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02003967 cancel_delayed_work(&conn->info_timer);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003968
Ville Tervoadb08ed2010-08-04 09:43:33 +03003969 if (result != L2CAP_IR_SUCCESS) {
3970 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3971 conn->info_ident = 0;
3972
3973 l2cap_conn_start(conn);
3974
3975 return 0;
3976 }
3977
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003978 switch (type) {
3979 case L2CAP_IT_FEAT_MASK:
Harvey Harrison83985312008-05-02 16:25:46 -07003980 conn->feat_mask = get_unaligned_le32(rsp->data);
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02003981
Marcel Holtmann47ec1dcd2009-05-02 18:57:55 -07003982 if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
Marcel Holtmanne1027a72009-02-09 09:18:02 +01003983 struct l2cap_info_req req;
3984 req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
3985
3986 conn->info_ident = l2cap_get_ident(conn);
3987
3988 l2cap_send_cmd(conn, conn->info_ident,
3989 L2CAP_INFO_REQ, sizeof(req), &req);
3990 } else {
3991 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3992 conn->info_ident = 0;
3993
3994 l2cap_conn_start(conn);
3995 }
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02003996 break;
3997
3998 case L2CAP_IT_FIXED_CHAN:
3999 conn->fixed_chan_mask = rsp->data[0];
Marcel Holtmann984947d2009-02-06 23:35:19 +01004000 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
Marcel Holtmanne1027a72009-02-09 09:18:02 +01004001 conn->info_ident = 0;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004002
4003 l2cap_conn_start(conn);
Andrei Emeltchenko978c93b2012-02-29 10:41:41 +02004004 break;
Marcel Holtmann984947d2009-02-06 23:35:19 +01004005 }
Marcel Holtmann4e8402a2007-10-20 13:37:56 +02004006
Linus Torvalds1da177e2005-04-16 15:20:36 -07004007 return 0;
4008}
4009
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004010static inline int l2cap_create_channel_req(struct l2cap_conn *conn,
4011 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4012 void *data)
4013{
4014 struct l2cap_create_chan_req *req = data;
4015 struct l2cap_create_chan_rsp rsp;
4016 u16 psm, scid;
4017
4018 if (cmd_len != sizeof(*req))
4019 return -EPROTO;
4020
4021 if (!enable_hs)
4022 return -EINVAL;
4023
4024 psm = le16_to_cpu(req->psm);
4025 scid = le16_to_cpu(req->scid);
4026
4027 BT_DBG("psm %d, scid %d, amp_id %d", psm, scid, req->amp_id);
4028
4029 /* Placeholder: Always reject */
4030 rsp.dcid = 0;
4031 rsp.scid = cpu_to_le16(scid);
Andrei Emeltchenko8ce0c492012-03-12 12:13:09 +02004032 rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
4033 rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004034
4035 l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
4036 sizeof(rsp), &rsp);
4037
4038 return 0;
4039}
4040
4041static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn,
4042 struct l2cap_cmd_hdr *cmd, void *data)
4043{
4044 BT_DBG("conn %p", conn);
4045
4046 return l2cap_connect_rsp(conn, cmd, data);
4047}
4048
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004049static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident,
4050 u16 icid, u16 result)
4051{
4052 struct l2cap_move_chan_rsp rsp;
4053
4054 BT_DBG("icid %d, result %d", icid, result);
4055
4056 rsp.icid = cpu_to_le16(icid);
4057 rsp.result = cpu_to_le16(result);
4058
4059 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_RSP, sizeof(rsp), &rsp);
4060}
4061
4062static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn,
4063 struct l2cap_chan *chan, u16 icid, u16 result)
4064{
4065 struct l2cap_move_chan_cfm cfm;
4066 u8 ident;
4067
4068 BT_DBG("icid %d, result %d", icid, result);
4069
4070 ident = l2cap_get_ident(conn);
4071 if (chan)
4072 chan->ident = ident;
4073
4074 cfm.icid = cpu_to_le16(icid);
4075 cfm.result = cpu_to_le16(result);
4076
4077 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM, sizeof(cfm), &cfm);
4078}
4079
4080static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
4081 u16 icid)
4082{
4083 struct l2cap_move_chan_cfm_rsp rsp;
4084
4085 BT_DBG("icid %d", icid);
4086
4087 rsp.icid = cpu_to_le16(icid);
4088 l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
4089}
4090
4091static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
4092 struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data)
4093{
4094 struct l2cap_move_chan_req *req = data;
4095 u16 icid = 0;
4096 u16 result = L2CAP_MR_NOT_ALLOWED;
4097
4098 if (cmd_len != sizeof(*req))
4099 return -EPROTO;
4100
4101 icid = le16_to_cpu(req->icid);
4102
4103 BT_DBG("icid %d, dest_amp_id %d", icid, req->dest_amp_id);
4104
4105 if (!enable_hs)
4106 return -EINVAL;
4107
4108 /* Placeholder: Always refuse */
4109 l2cap_send_move_chan_rsp(conn, cmd->ident, icid, result);
4110
4111 return 0;
4112}
4113
4114static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn,
4115 struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data)
4116{
4117 struct l2cap_move_chan_rsp *rsp = data;
4118 u16 icid, result;
4119
4120 if (cmd_len != sizeof(*rsp))
4121 return -EPROTO;
4122
4123 icid = le16_to_cpu(rsp->icid);
4124 result = le16_to_cpu(rsp->result);
4125
4126 BT_DBG("icid %d, result %d", icid, result);
4127
4128 /* Placeholder: Always unconfirmed */
4129 l2cap_send_move_chan_cfm(conn, NULL, icid, L2CAP_MC_UNCONFIRMED);
4130
4131 return 0;
4132}
4133
4134static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn,
4135 struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data)
4136{
4137 struct l2cap_move_chan_cfm *cfm = data;
4138 u16 icid, result;
4139
4140 if (cmd_len != sizeof(*cfm))
4141 return -EPROTO;
4142
4143 icid = le16_to_cpu(cfm->icid);
4144 result = le16_to_cpu(cfm->result);
4145
4146 BT_DBG("icid %d, result %d", icid, result);
4147
4148 l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
4149
4150 return 0;
4151}
4152
4153static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
4154 struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data)
4155{
4156 struct l2cap_move_chan_cfm_rsp *rsp = data;
4157 u16 icid;
4158
4159 if (cmd_len != sizeof(*rsp))
4160 return -EPROTO;
4161
4162 icid = le16_to_cpu(rsp->icid);
4163
4164 BT_DBG("icid %d", icid);
4165
4166 return 0;
4167}
4168
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004169static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
Claudio Takahaside731152011-02-11 19:28:55 -02004170 u16 to_multiplier)
4171{
4172 u16 max_latency;
4173
4174 if (min > max || min < 6 || max > 3200)
4175 return -EINVAL;
4176
4177 if (to_multiplier < 10 || to_multiplier > 3200)
4178 return -EINVAL;
4179
4180 if (max >= to_multiplier * 8)
4181 return -EINVAL;
4182
4183 max_latency = (to_multiplier * 8 / max) - 1;
4184 if (latency > 499 || latency > max_latency)
4185 return -EINVAL;
4186
4187 return 0;
4188}
4189
4190static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
4191 struct l2cap_cmd_hdr *cmd, u8 *data)
4192{
4193 struct hci_conn *hcon = conn->hcon;
4194 struct l2cap_conn_param_update_req *req;
4195 struct l2cap_conn_param_update_rsp rsp;
4196 u16 min, max, latency, to_multiplier, cmd_len;
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004197 int err;
Claudio Takahaside731152011-02-11 19:28:55 -02004198
4199 if (!(hcon->link_mode & HCI_LM_MASTER))
4200 return -EINVAL;
4201
4202 cmd_len = __le16_to_cpu(cmd->len);
4203 if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
4204 return -EPROTO;
4205
4206 req = (struct l2cap_conn_param_update_req *) data;
Gustavo F. Padovane2174ca2011-02-17 19:16:55 -03004207 min = __le16_to_cpu(req->min);
4208 max = __le16_to_cpu(req->max);
Claudio Takahaside731152011-02-11 19:28:55 -02004209 latency = __le16_to_cpu(req->latency);
4210 to_multiplier = __le16_to_cpu(req->to_multiplier);
4211
4212 BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
4213 min, max, latency, to_multiplier);
4214
4215 memset(&rsp, 0, sizeof(rsp));
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004216
4217 err = l2cap_check_conn_param(min, max, latency, to_multiplier);
4218 if (err)
Claudio Takahaside731152011-02-11 19:28:55 -02004219 rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
4220 else
4221 rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
4222
4223 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
4224 sizeof(rsp), &rsp);
4225
Claudio Takahasi2ce603e2011-02-16 20:44:53 -02004226 if (!err)
4227 hci_le_conn_update(hcon, min, max, latency, to_multiplier);
4228
Claudio Takahaside731152011-02-11 19:28:55 -02004229 return 0;
4230}
4231
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004232static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
4233 struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
4234{
4235 int err = 0;
4236
4237 switch (cmd->code) {
4238 case L2CAP_COMMAND_REJ:
4239 l2cap_command_rej(conn, cmd, data);
4240 break;
4241
4242 case L2CAP_CONN_REQ:
4243 err = l2cap_connect_req(conn, cmd, data);
4244 break;
4245
4246 case L2CAP_CONN_RSP:
4247 err = l2cap_connect_rsp(conn, cmd, data);
4248 break;
4249
4250 case L2CAP_CONF_REQ:
4251 err = l2cap_config_req(conn, cmd, cmd_len, data);
4252 break;
4253
4254 case L2CAP_CONF_RSP:
4255 err = l2cap_config_rsp(conn, cmd, data);
4256 break;
4257
4258 case L2CAP_DISCONN_REQ:
4259 err = l2cap_disconnect_req(conn, cmd, data);
4260 break;
4261
4262 case L2CAP_DISCONN_RSP:
4263 err = l2cap_disconnect_rsp(conn, cmd, data);
4264 break;
4265
4266 case L2CAP_ECHO_REQ:
4267 l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
4268 break;
4269
4270 case L2CAP_ECHO_RSP:
4271 break;
4272
4273 case L2CAP_INFO_REQ:
4274 err = l2cap_information_req(conn, cmd, data);
4275 break;
4276
4277 case L2CAP_INFO_RSP:
4278 err = l2cap_information_rsp(conn, cmd, data);
4279 break;
4280
Mat Martineauf94ff6f2011-11-02 16:18:32 -07004281 case L2CAP_CREATE_CHAN_REQ:
4282 err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
4283 break;
4284
4285 case L2CAP_CREATE_CHAN_RSP:
4286 err = l2cap_create_channel_rsp(conn, cmd, data);
4287 break;
4288
Mat Martineau8d5a04a2011-11-02 16:18:35 -07004289 case L2CAP_MOVE_CHAN_REQ:
4290 err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
4291 break;
4292
4293 case L2CAP_MOVE_CHAN_RSP:
4294 err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data);
4295 break;
4296
4297 case L2CAP_MOVE_CHAN_CFM:
4298 err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data);
4299 break;
4300
4301 case L2CAP_MOVE_CHAN_CFM_RSP:
4302 err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data);
4303 break;
4304
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004305 default:
4306 BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
4307 err = -EINVAL;
4308 break;
4309 }
4310
4311 return err;
4312}
4313
4314static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
4315 struct l2cap_cmd_hdr *cmd, u8 *data)
4316{
4317 switch (cmd->code) {
4318 case L2CAP_COMMAND_REJ:
4319 return 0;
4320
4321 case L2CAP_CONN_PARAM_UPDATE_REQ:
Claudio Takahaside731152011-02-11 19:28:55 -02004322 return l2cap_conn_param_update_req(conn, cmd, data);
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004323
4324 case L2CAP_CONN_PARAM_UPDATE_RSP:
4325 return 0;
4326
4327 default:
4328 BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
4329 return -EINVAL;
4330 }
4331}
4332
4333static inline void l2cap_sig_channel(struct l2cap_conn *conn,
4334 struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004335{
4336 u8 *data = skb->data;
4337 int len = skb->len;
4338 struct l2cap_cmd_hdr cmd;
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004339 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004340
4341 l2cap_raw_recv(conn, skb);
4342
4343 while (len >= L2CAP_CMD_HDR_SIZE) {
Al Viro88219a02007-07-29 00:17:25 -07004344 u16 cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004345 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
4346 data += L2CAP_CMD_HDR_SIZE;
4347 len -= L2CAP_CMD_HDR_SIZE;
4348
Al Viro88219a02007-07-29 00:17:25 -07004349 cmd_len = le16_to_cpu(cmd.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004350
Al Viro88219a02007-07-29 00:17:25 -07004351 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len, cmd.ident);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004352
Al Viro88219a02007-07-29 00:17:25 -07004353 if (cmd_len > len || !cmd.ident) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004354 BT_DBG("corrupted command");
4355 break;
4356 }
4357
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02004358 if (conn->hcon->type == LE_LINK)
4359 err = l2cap_le_sig_cmd(conn, &cmd, data);
4360 else
4361 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004362
4363 if (err) {
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004364 struct l2cap_cmd_rej_unk rej;
Gustavo F. Padovan2c6d1a22011-03-23 14:38:32 -03004365
4366 BT_ERR("Wrong link type (%d)", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004367
4368 /* FIXME: Map err to a valid reason */
Ilia Kolomisnkye2fd3182011-07-10 08:47:44 +03004369 rej.reason = cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004370 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
4371 }
4372
Al Viro88219a02007-07-29 00:17:25 -07004373 data += cmd_len;
4374 len -= cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004375 }
4376
4377 kfree_skb(skb);
4378}
4379
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004380static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb)
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004381{
4382 u16 our_fcs, rcv_fcs;
Andrei Emeltchenkoe4ca6d92011-10-11 13:37:52 +03004383 int hdr_size;
4384
4385 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
4386 hdr_size = L2CAP_EXT_HDR_SIZE;
4387 else
4388 hdr_size = L2CAP_ENH_HDR_SIZE;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004389
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03004390 if (chan->fcs == L2CAP_FCS_CRC16) {
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004391 skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004392 rcv_fcs = get_unaligned_le16(skb->data + skb->len);
4393 our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
4394
4395 if (our_fcs != rcv_fcs)
João Paulo Rechi Vita7a560e52010-06-22 13:56:27 -03004396 return -EBADMSG;
Gustavo F. Padovanfcc203c2009-08-20 22:26:02 -03004397 }
4398 return 0;
4399}
4400
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03004401static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004402{
Mat Martineaue31f7632012-05-17 20:53:41 -07004403 struct l2cap_ctrl control;
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004404
Mat Martineaue31f7632012-05-17 20:53:41 -07004405 BT_DBG("chan %p", chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004406
Mat Martineaue31f7632012-05-17 20:53:41 -07004407 memset(&control, 0, sizeof(control));
4408 control.sframe = 1;
4409 control.final = 1;
4410 control.reqseq = chan->buffer_seq;
4411 set_bit(CONN_SEND_FBIT, &chan->conn_state);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004412
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004413 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
Mat Martineaue31f7632012-05-17 20:53:41 -07004414 control.super = L2CAP_SUPER_RNR;
4415 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004416 }
4417
Mat Martineaue31f7632012-05-17 20:53:41 -07004418 if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
4419 chan->unacked_frames > 0)
4420 __set_retrans_timer(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004421
Mat Martineaue31f7632012-05-17 20:53:41 -07004422 /* Send pending iframes */
Gustavo F. Padovan525cd182011-03-25 19:43:39 -03004423 l2cap_ertm_send(chan);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004424
Gustavo F. Padovane2ab4352011-06-10 21:28:49 -03004425 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
Mat Martineaue31f7632012-05-17 20:53:41 -07004426 test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
4427 /* F-bit wasn't sent in an s-frame or i-frame yet, so
4428 * send it now.
4429 */
4430 control.super = L2CAP_SUPER_RR;
4431 l2cap_send_sframe(chan, &control);
Gustavo F. Padovand5392c82010-05-01 16:15:36 -03004432 }
4433}
4434
Mat Martineau84084a32011-07-22 14:54:00 -07004435static void append_skb_frag(struct sk_buff *skb,
4436 struct sk_buff *new_frag, struct sk_buff **last_frag)
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004437{
Mat Martineau84084a32011-07-22 14:54:00 -07004438 /* skb->len reflects data in skb as well as all fragments
4439 * skb->data_len reflects only data in fragments
4440 */
4441 if (!skb_has_frag_list(skb))
4442 skb_shinfo(skb)->frag_list = new_frag;
4443
4444 new_frag->next = NULL;
4445
4446 (*last_frag)->next = new_frag;
4447 *last_frag = new_frag;
4448
4449 skb->len += new_frag->len;
4450 skb->data_len += new_frag->len;
4451 skb->truesize += new_frag->truesize;
4452}
4453
Mat Martineau4b51dae92012-05-17 20:53:37 -07004454static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
4455 struct l2cap_ctrl *control)
Mat Martineau84084a32011-07-22 14:54:00 -07004456{
4457 int err = -EINVAL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004458
Mat Martineau4b51dae92012-05-17 20:53:37 -07004459 switch (control->sar) {
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004460 case L2CAP_SAR_UNSEGMENTED:
Mat Martineau84084a32011-07-22 14:54:00 -07004461 if (chan->sdu)
4462 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004463
Mat Martineau84084a32011-07-22 14:54:00 -07004464 err = chan->ops->recv(chan->data, skb);
4465 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004466
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004467 case L2CAP_SAR_START:
Mat Martineau84084a32011-07-22 14:54:00 -07004468 if (chan->sdu)
4469 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004470
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004471 chan->sdu_len = get_unaligned_le16(skb->data);
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03004472 skb_pull(skb, L2CAP_SDULEN_SIZE);
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004473
Mat Martineau84084a32011-07-22 14:54:00 -07004474 if (chan->sdu_len > chan->imtu) {
4475 err = -EMSGSIZE;
4476 break;
4477 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004478
Mat Martineau84084a32011-07-22 14:54:00 -07004479 if (skb->len >= chan->sdu_len)
4480 break;
4481
4482 chan->sdu = skb;
4483 chan->sdu_last_frag = skb;
4484
4485 skb = NULL;
4486 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004487 break;
4488
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004489 case L2CAP_SAR_CONTINUE:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004490 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004491 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004492
Mat Martineau84084a32011-07-22 14:54:00 -07004493 append_skb_frag(chan->sdu, skb,
4494 &chan->sdu_last_frag);
4495 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004496
Mat Martineau84084a32011-07-22 14:54:00 -07004497 if (chan->sdu->len >= chan->sdu_len)
4498 break;
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004499
Mat Martineau84084a32011-07-22 14:54:00 -07004500 err = 0;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004501 break;
4502
Andrei Emeltchenko7e0ef6e2011-10-11 13:37:45 +03004503 case L2CAP_SAR_END:
Gustavo F. Padovan6f61fd472011-03-25 20:09:37 -03004504 if (!chan->sdu)
Mat Martineau84084a32011-07-22 14:54:00 -07004505 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004506
Mat Martineau84084a32011-07-22 14:54:00 -07004507 append_skb_frag(chan->sdu, skb,
4508 &chan->sdu_last_frag);
4509 skb = NULL;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004510
Mat Martineau84084a32011-07-22 14:54:00 -07004511 if (chan->sdu->len != chan->sdu_len)
4512 break;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004513
Mat Martineau84084a32011-07-22 14:54:00 -07004514 err = chan->ops->recv(chan->data, chan->sdu);
Gustavo F. Padovan4178ba42010-05-01 16:15:45 -03004515
Mat Martineau84084a32011-07-22 14:54:00 -07004516 if (!err) {
4517 /* Reassembly complete */
4518 chan->sdu = NULL;
4519 chan->sdu_last_frag = NULL;
4520 chan->sdu_len = 0;
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004521 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004522 break;
4523 }
4524
Mat Martineau84084a32011-07-22 14:54:00 -07004525 if (err) {
4526 kfree_skb(skb);
4527 kfree_skb(chan->sdu);
4528 chan->sdu = NULL;
4529 chan->sdu_last_frag = NULL;
4530 chan->sdu_len = 0;
4531 }
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004532
Mat Martineau84084a32011-07-22 14:54:00 -07004533 return err;
Gustavo F. Padovan18778a62010-05-01 16:15:44 -03004534}
4535
Mat Martineaue3281402011-07-07 09:39:02 -07004536void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
Gustavo F. Padovan712132e2010-06-21 19:39:50 -03004537{
Mat Martineau61aa4f52012-05-17 20:53:40 -07004538 u8 event;
4539
4540 if (chan->mode != L2CAP_MODE_ERTM)
4541 return;
4542
4543 event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
4544 l2cap_tx(chan, 0, 0, event);
Gustavo F. Padovan1890d362010-05-01 16:15:44 -03004545}
4546
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004547static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
4548{
Mat Martineau63838722012-05-17 20:53:45 -07004549 int err = 0;
4550 /* Pass sequential frames to l2cap_reassemble_sdu()
4551 * until a gap is encountered.
4552 */
4553
4554 BT_DBG("chan %p", chan);
4555
4556 while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4557 struct sk_buff *skb;
4558 BT_DBG("Searching for skb with txseq %d (queue len %d)",
4559 chan->buffer_seq, skb_queue_len(&chan->srej_q));
4560
4561 skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
4562
4563 if (!skb)
4564 break;
4565
4566 skb_unlink(skb, &chan->srej_q);
4567 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
4568 err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control);
4569 if (err)
4570 break;
4571 }
4572
4573 if (skb_queue_empty(&chan->srej_q)) {
4574 chan->rx_state = L2CAP_RX_STATE_RECV;
4575 l2cap_send_ack(chan);
4576 }
4577
4578 return err;
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004579}
4580
4581static void l2cap_handle_srej(struct l2cap_chan *chan,
4582 struct l2cap_ctrl *control)
4583{
Mat Martineauf80842a2012-05-17 20:53:46 -07004584 struct sk_buff *skb;
4585
4586 BT_DBG("chan %p, control %p", chan, control);
4587
4588 if (control->reqseq == chan->next_tx_seq) {
4589 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4590 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4591 return;
4592 }
4593
4594 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4595
4596 if (skb == NULL) {
4597 BT_DBG("Seq %d not available for retransmission",
4598 control->reqseq);
4599 return;
4600 }
4601
4602 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
4603 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4604 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4605 return;
4606 }
4607
4608 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4609
4610 if (control->poll) {
4611 l2cap_pass_to_tx(chan, control);
4612
4613 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4614 l2cap_retransmit(chan, control);
4615 l2cap_ertm_send(chan);
4616
4617 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4618 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4619 chan->srej_save_reqseq = control->reqseq;
4620 }
4621 } else {
4622 l2cap_pass_to_tx_fbit(chan, control);
4623
4624 if (control->final) {
4625 if (chan->srej_save_reqseq != control->reqseq ||
4626 !test_and_clear_bit(CONN_SREJ_ACT,
4627 &chan->conn_state))
4628 l2cap_retransmit(chan, control);
4629 } else {
4630 l2cap_retransmit(chan, control);
4631 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
4632 set_bit(CONN_SREJ_ACT, &chan->conn_state);
4633 chan->srej_save_reqseq = control->reqseq;
4634 }
4635 }
4636 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004637}
4638
4639static void l2cap_handle_rej(struct l2cap_chan *chan,
4640 struct l2cap_ctrl *control)
4641{
Mat Martineaufcd289d2012-05-17 20:53:47 -07004642 struct sk_buff *skb;
4643
4644 BT_DBG("chan %p, control %p", chan, control);
4645
4646 if (control->reqseq == chan->next_tx_seq) {
4647 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
4648 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4649 return;
4650 }
4651
4652 skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
4653
4654 if (chan->max_tx && skb &&
4655 bt_cb(skb)->control.retries >= chan->max_tx) {
4656 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
4657 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4658 return;
4659 }
4660
4661 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4662
4663 l2cap_pass_to_tx(chan, control);
4664
4665 if (control->final) {
4666 if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
4667 l2cap_retransmit_all(chan, control);
4668 } else {
4669 l2cap_retransmit_all(chan, control);
4670 l2cap_ertm_send(chan);
4671 if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
4672 set_bit(CONN_REJ_ACT, &chan->conn_state);
4673 }
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004674}
4675
Mat Martineau4b51dae92012-05-17 20:53:37 -07004676static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
4677{
4678 BT_DBG("chan %p, txseq %d", chan, txseq);
4679
4680 BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
4681 chan->expected_tx_seq);
4682
4683 if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
4684 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4685 chan->tx_win) {
4686 /* See notes below regarding "double poll" and
4687 * invalid packets.
4688 */
4689 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4690 BT_DBG("Invalid/Ignore - after SREJ");
4691 return L2CAP_TXSEQ_INVALID_IGNORE;
4692 } else {
4693 BT_DBG("Invalid - in window after SREJ sent");
4694 return L2CAP_TXSEQ_INVALID;
4695 }
4696 }
4697
4698 if (chan->srej_list.head == txseq) {
4699 BT_DBG("Expected SREJ");
4700 return L2CAP_TXSEQ_EXPECTED_SREJ;
4701 }
4702
4703 if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
4704 BT_DBG("Duplicate SREJ - txseq already stored");
4705 return L2CAP_TXSEQ_DUPLICATE_SREJ;
4706 }
4707
4708 if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
4709 BT_DBG("Unexpected SREJ - not requested");
4710 return L2CAP_TXSEQ_UNEXPECTED_SREJ;
4711 }
4712 }
4713
4714 if (chan->expected_tx_seq == txseq) {
4715 if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
4716 chan->tx_win) {
4717 BT_DBG("Invalid - txseq outside tx window");
4718 return L2CAP_TXSEQ_INVALID;
4719 } else {
4720 BT_DBG("Expected");
4721 return L2CAP_TXSEQ_EXPECTED;
4722 }
4723 }
4724
4725 if (__seq_offset(chan, txseq, chan->last_acked_seq) <
4726 __seq_offset(chan, chan->expected_tx_seq,
4727 chan->last_acked_seq)){
4728 BT_DBG("Duplicate - expected_tx_seq later than txseq");
4729 return L2CAP_TXSEQ_DUPLICATE;
4730 }
4731
4732 if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
4733 /* A source of invalid packets is a "double poll" condition,
4734 * where delays cause us to send multiple poll packets. If
4735 * the remote stack receives and processes both polls,
4736 * sequence numbers can wrap around in such a way that a
4737 * resent frame has a sequence number that looks like new data
4738 * with a sequence gap. This would trigger an erroneous SREJ
4739 * request.
4740 *
4741 * Fortunately, this is impossible with a tx window that's
4742 * less than half of the maximum sequence number, which allows
4743 * invalid frames to be safely ignored.
4744 *
4745 * With tx window sizes greater than half of the tx window
4746 * maximum, the frame is invalid and cannot be ignored. This
4747 * causes a disconnect.
4748 */
4749
4750 if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
4751 BT_DBG("Invalid/Ignore - txseq outside tx window");
4752 return L2CAP_TXSEQ_INVALID_IGNORE;
4753 } else {
4754 BT_DBG("Invalid - txseq outside tx window");
4755 return L2CAP_TXSEQ_INVALID;
4756 }
4757 } else {
4758 BT_DBG("Unexpected - txseq indicates missing frames");
4759 return L2CAP_TXSEQ_UNEXPECTED;
4760 }
4761}
4762
Mat Martineaud2a7ac52012-05-17 20:53:42 -07004763static int l2cap_rx_state_recv(struct l2cap_chan *chan,
4764 struct l2cap_ctrl *control,
4765 struct sk_buff *skb, u8 event)
4766{
4767 int err = 0;
4768 bool skb_in_use = 0;
4769
4770 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4771 event);
4772
4773 switch (event) {
4774 case L2CAP_EV_RECV_IFRAME:
4775 switch (l2cap_classify_txseq(chan, control->txseq)) {
4776 case L2CAP_TXSEQ_EXPECTED:
4777 l2cap_pass_to_tx(chan, control);
4778
4779 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4780 BT_DBG("Busy, discarding expected seq %d",
4781 control->txseq);
4782 break;
4783 }
4784
4785 chan->expected_tx_seq = __next_seq(chan,
4786 control->txseq);
4787
4788 chan->buffer_seq = chan->expected_tx_seq;
4789 skb_in_use = 1;
4790
4791 err = l2cap_reassemble_sdu(chan, skb, control);
4792 if (err)
4793 break;
4794
4795 if (control->final) {
4796 if (!test_and_clear_bit(CONN_REJ_ACT,
4797 &chan->conn_state)) {
4798 control->final = 0;
4799 l2cap_retransmit_all(chan, control);
4800 l2cap_ertm_send(chan);
4801 }
4802 }
4803
4804 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
4805 l2cap_send_ack(chan);
4806 break;
4807 case L2CAP_TXSEQ_UNEXPECTED:
4808 l2cap_pass_to_tx(chan, control);
4809
4810 /* Can't issue SREJ frames in the local busy state.
4811 * Drop this frame, it will be seen as missing
4812 * when local busy is exited.
4813 */
4814 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4815 BT_DBG("Busy, discarding unexpected seq %d",
4816 control->txseq);
4817 break;
4818 }
4819
4820 /* There was a gap in the sequence, so an SREJ
4821 * must be sent for each missing frame. The
4822 * current frame is stored for later use.
4823 */
4824 skb_queue_tail(&chan->srej_q, skb);
4825 skb_in_use = 1;
4826 BT_DBG("Queued %p (queue len %d)", skb,
4827 skb_queue_len(&chan->srej_q));
4828
4829 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
4830 l2cap_seq_list_clear(&chan->srej_list);
4831 l2cap_send_srej(chan, control->txseq);
4832
4833 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
4834 break;
4835 case L2CAP_TXSEQ_DUPLICATE:
4836 l2cap_pass_to_tx(chan, control);
4837 break;
4838 case L2CAP_TXSEQ_INVALID_IGNORE:
4839 break;
4840 case L2CAP_TXSEQ_INVALID:
4841 default:
4842 l2cap_send_disconn_req(chan->conn, chan,
4843 ECONNRESET);
4844 break;
4845 }
4846 break;
4847 case L2CAP_EV_RECV_RR:
4848 l2cap_pass_to_tx(chan, control);
4849 if (control->final) {
4850 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4851
4852 if (!test_and_clear_bit(CONN_REJ_ACT,
4853 &chan->conn_state)) {
4854 control->final = 0;
4855 l2cap_retransmit_all(chan, control);
4856 }
4857
4858 l2cap_ertm_send(chan);
4859 } else if (control->poll) {
4860 l2cap_send_i_or_rr_or_rnr(chan);
4861 } else {
4862 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4863 &chan->conn_state) &&
4864 chan->unacked_frames)
4865 __set_retrans_timer(chan);
4866
4867 l2cap_ertm_send(chan);
4868 }
4869 break;
4870 case L2CAP_EV_RECV_RNR:
4871 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4872 l2cap_pass_to_tx(chan, control);
4873 if (control && control->poll) {
4874 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4875 l2cap_send_rr_or_rnr(chan, 0);
4876 }
4877 __clear_retrans_timer(chan);
4878 l2cap_seq_list_clear(&chan->retrans_list);
4879 break;
4880 case L2CAP_EV_RECV_REJ:
4881 l2cap_handle_rej(chan, control);
4882 break;
4883 case L2CAP_EV_RECV_SREJ:
4884 l2cap_handle_srej(chan, control);
4885 break;
4886 default:
4887 break;
4888 }
4889
4890 if (skb && !skb_in_use) {
4891 BT_DBG("Freeing %p", skb);
4892 kfree_skb(skb);
4893 }
4894
4895 return err;
4896}
4897
4898static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
4899 struct l2cap_ctrl *control,
4900 struct sk_buff *skb, u8 event)
4901{
4902 int err = 0;
4903 u16 txseq = control->txseq;
4904 bool skb_in_use = 0;
4905
4906 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4907 event);
4908
4909 switch (event) {
4910 case L2CAP_EV_RECV_IFRAME:
4911 switch (l2cap_classify_txseq(chan, txseq)) {
4912 case L2CAP_TXSEQ_EXPECTED:
4913 /* Keep frame for reassembly later */
4914 l2cap_pass_to_tx(chan, control);
4915 skb_queue_tail(&chan->srej_q, skb);
4916 skb_in_use = 1;
4917 BT_DBG("Queued %p (queue len %d)", skb,
4918 skb_queue_len(&chan->srej_q));
4919
4920 chan->expected_tx_seq = __next_seq(chan, txseq);
4921 break;
4922 case L2CAP_TXSEQ_EXPECTED_SREJ:
4923 l2cap_seq_list_pop(&chan->srej_list);
4924
4925 l2cap_pass_to_tx(chan, control);
4926 skb_queue_tail(&chan->srej_q, skb);
4927 skb_in_use = 1;
4928 BT_DBG("Queued %p (queue len %d)", skb,
4929 skb_queue_len(&chan->srej_q));
4930
4931 err = l2cap_rx_queued_iframes(chan);
4932 if (err)
4933 break;
4934
4935 break;
4936 case L2CAP_TXSEQ_UNEXPECTED:
4937 /* Got a frame that can't be reassembled yet.
4938 * Save it for later, and send SREJs to cover
4939 * the missing frames.
4940 */
4941 skb_queue_tail(&chan->srej_q, skb);
4942 skb_in_use = 1;
4943 BT_DBG("Queued %p (queue len %d)", skb,
4944 skb_queue_len(&chan->srej_q));
4945
4946 l2cap_pass_to_tx(chan, control);
4947 l2cap_send_srej(chan, control->txseq);
4948 break;
4949 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
4950 /* This frame was requested with an SREJ, but
4951 * some expected retransmitted frames are
4952 * missing. Request retransmission of missing
4953 * SREJ'd frames.
4954 */
4955 skb_queue_tail(&chan->srej_q, skb);
4956 skb_in_use = 1;
4957 BT_DBG("Queued %p (queue len %d)", skb,
4958 skb_queue_len(&chan->srej_q));
4959
4960 l2cap_pass_to_tx(chan, control);
4961 l2cap_send_srej_list(chan, control->txseq);
4962 break;
4963 case L2CAP_TXSEQ_DUPLICATE_SREJ:
4964 /* We've already queued this frame. Drop this copy. */
4965 l2cap_pass_to_tx(chan, control);
4966 break;
4967 case L2CAP_TXSEQ_DUPLICATE:
4968 /* Expecting a later sequence number, so this frame
4969 * was already received. Ignore it completely.
4970 */
4971 break;
4972 case L2CAP_TXSEQ_INVALID_IGNORE:
4973 break;
4974 case L2CAP_TXSEQ_INVALID:
4975 default:
4976 l2cap_send_disconn_req(chan->conn, chan,
4977 ECONNRESET);
4978 break;
4979 }
4980 break;
4981 case L2CAP_EV_RECV_RR:
4982 l2cap_pass_to_tx(chan, control);
4983 if (control->final) {
4984 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4985
4986 if (!test_and_clear_bit(CONN_REJ_ACT,
4987 &chan->conn_state)) {
4988 control->final = 0;
4989 l2cap_retransmit_all(chan, control);
4990 }
4991
4992 l2cap_ertm_send(chan);
4993 } else if (control->poll) {
4994 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4995 &chan->conn_state) &&
4996 chan->unacked_frames) {
4997 __set_retrans_timer(chan);
4998 }
4999
5000 set_bit(CONN_SEND_FBIT, &chan->conn_state);
5001 l2cap_send_srej_tail(chan);
5002 } else {
5003 if (test_and_clear_bit(CONN_REMOTE_BUSY,
5004 &chan->conn_state) &&
5005 chan->unacked_frames)
5006 __set_retrans_timer(chan);
5007
5008 l2cap_send_ack(chan);
5009 }
5010 break;
5011 case L2CAP_EV_RECV_RNR:
5012 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5013 l2cap_pass_to_tx(chan, control);
5014 if (control->poll) {
5015 l2cap_send_srej_tail(chan);
5016 } else {
5017 struct l2cap_ctrl rr_control;
5018 memset(&rr_control, 0, sizeof(rr_control));
5019 rr_control.sframe = 1;
5020 rr_control.super = L2CAP_SUPER_RR;
5021 rr_control.reqseq = chan->buffer_seq;
5022 l2cap_send_sframe(chan, &rr_control);
5023 }
5024
5025 break;
5026 case L2CAP_EV_RECV_REJ:
5027 l2cap_handle_rej(chan, control);
5028 break;
5029 case L2CAP_EV_RECV_SREJ:
5030 l2cap_handle_srej(chan, control);
5031 break;
5032 }
5033
5034 if (skb && !skb_in_use) {
5035 BT_DBG("Freeing %p", skb);
5036 kfree_skb(skb);
5037 }
5038
5039 return err;
5040}
5041
5042static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
5043{
5044 /* Make sure reqseq is for a packet that has been sent but not acked */
5045 u16 unacked;
5046
5047 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
5048 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
5049}
5050
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005051static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5052 struct sk_buff *skb, u8 event)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005053{
Mat Martineaud2a7ac52012-05-17 20:53:42 -07005054 int err = 0;
5055
5056 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
5057 control, skb, event, chan->rx_state);
5058
5059 if (__valid_reqseq(chan, control->reqseq)) {
5060 switch (chan->rx_state) {
5061 case L2CAP_RX_STATE_RECV:
5062 err = l2cap_rx_state_recv(chan, control, skb, event);
5063 break;
5064 case L2CAP_RX_STATE_SREJ_SENT:
5065 err = l2cap_rx_state_srej_sent(chan, control, skb,
5066 event);
5067 break;
5068 default:
5069 /* shut it down */
5070 break;
5071 }
5072 } else {
5073 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
5074 control->reqseq, chan->next_tx_seq,
5075 chan->expected_ack_seq);
5076 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
5077 }
5078
5079 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005080}
5081
5082static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5083 struct sk_buff *skb)
5084{
Mat Martineau4b51dae92012-05-17 20:53:37 -07005085 int err = 0;
5086
5087 BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
5088 chan->rx_state);
5089
5090 if (l2cap_classify_txseq(chan, control->txseq) ==
5091 L2CAP_TXSEQ_EXPECTED) {
5092 l2cap_pass_to_tx(chan, control);
5093
5094 BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
5095 __next_seq(chan, chan->buffer_seq));
5096
5097 chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5098
5099 l2cap_reassemble_sdu(chan, skb, control);
5100 } else {
5101 if (chan->sdu) {
5102 kfree_skb(chan->sdu);
5103 chan->sdu = NULL;
5104 }
5105 chan->sdu_last_frag = NULL;
5106 chan->sdu_len = 0;
5107
5108 if (skb) {
5109 BT_DBG("Freeing %p", skb);
5110 kfree_skb(skb);
5111 }
5112 }
5113
5114 chan->last_acked_seq = control->txseq;
5115 chan->expected_tx_seq = __next_seq(chan, control->txseq);
5116
5117 return err;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005118}
5119
5120static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
5121{
5122 struct l2cap_ctrl *control = &bt_cb(skb)->control;
5123 u16 len;
5124 u8 event;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005125
Mat Martineaub76bbd62012-04-11 10:48:43 -07005126 __unpack_control(chan, skb);
5127
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005128 len = skb->len;
5129
5130 /*
5131 * We can just drop the corrupted I-frame here.
5132 * Receiver will miss it and start proper recovery
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005133 * procedures and ask for retransmission.
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005134 */
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005135 if (l2cap_check_fcs(chan, skb))
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005136 goto drop;
5137
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005138 if (!control->sframe && control->sar == L2CAP_SAR_START)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005139 len -= L2CAP_SDULEN_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005140
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005141 if (chan->fcs == L2CAP_FCS_CRC16)
Andrei Emeltchenko03a51212011-10-17 12:19:58 +03005142 len -= L2CAP_FCS_SIZE;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005143
Gustavo F. Padovan47d1ec62011-04-13 15:57:03 -03005144 if (len > chan->mps) {
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005145 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005146 goto drop;
5147 }
5148
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005149 if (!control->sframe) {
5150 int err;
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005151
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005152 BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
5153 control->sar, control->reqseq, control->final,
5154 control->txseq);
Andrei Emeltchenko836be932011-10-17 12:19:57 +03005155
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005156 /* Validate F-bit - F=0 always valid, F=1 only
5157 * valid in TX WAIT_F
5158 */
5159 if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005160 goto drop;
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005161
5162 if (chan->mode != L2CAP_MODE_STREAMING) {
5163 event = L2CAP_EV_RECV_IFRAME;
5164 err = l2cap_rx(chan, control, skb, event);
5165 } else {
5166 err = l2cap_stream_rx(chan, control, skb);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005167 }
5168
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005169 if (err)
5170 l2cap_send_disconn_req(chan->conn, chan,
5171 ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005172 } else {
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005173 const u8 rx_func_to_event[4] = {
5174 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
5175 L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
5176 };
5177
5178 /* Only I-frames are expected in streaming mode */
5179 if (chan->mode == L2CAP_MODE_STREAMING)
5180 goto drop;
5181
5182 BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
5183 control->reqseq, control->final, control->poll,
5184 control->super);
5185
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005186 if (len != 0) {
5187 BT_ERR("%d", len);
Gustavo F. Padovan8c1d7872011-04-13 20:23:55 -03005188 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005189 goto drop;
5190 }
5191
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005192 /* Validate F and P bits */
5193 if (control->final && (control->poll ||
5194 chan->tx_state != L2CAP_TX_STATE_WAIT_F))
5195 goto drop;
5196
5197 event = rx_func_to_event[control->super];
5198 if (l2cap_rx(chan, control, skb, event))
5199 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
Gustavo F. Padovan218bb9d2010-06-21 18:53:22 -03005200 }
5201
5202 return 0;
5203
5204drop:
5205 kfree_skb(skb);
5206 return 0;
5207}
5208
Linus Torvalds1da177e2005-04-16 15:20:36 -07005209static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
5210{
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005211 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005212
Gustavo F. Padovanbaa7e1f2011-03-31 16:17:41 -03005213 chan = l2cap_get_chan_by_scid(conn, cid);
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005214 if (!chan) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005215 BT_DBG("unknown cid 0x%4.4x", cid);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005216 /* Drop packet and return */
Dan Carpenter33790132012-02-28 09:52:46 +03005217 kfree_skb(skb);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005218 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005219 }
5220
Gustavo F. Padovan49208c92011-04-04 15:59:54 -03005221 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005222
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005223 if (chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005224 goto drop;
5225
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005226 switch (chan->mode) {
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005227 case L2CAP_MODE_BASIC:
5228 /* If socket recv buffers overflows we drop data here
5229 * which is *bad* because L2CAP has to be reliable.
5230 * But we don't have any other choice. L2CAP doesn't
5231 * provide flow control mechanism. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005232
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005233 if (chan->imtu < skb->len)
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005234 goto drop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005235
Gustavo F. Padovan23070492011-05-16 17:57:22 -03005236 if (!chan->ops->recv(chan->data, skb))
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005237 goto done;
5238 break;
5239
5240 case L2CAP_MODE_ERTM:
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005241 case L2CAP_MODE_STREAMING:
Mat Martineaucec8ab6e2012-05-17 20:53:36 -07005242 l2cap_data_rcv(chan, skb);
Gustavo F. Padovan6840ed02009-08-20 22:26:01 -03005243 goto done;
5244
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005245 default:
Gustavo F. Padovan0c1bc5c2011-04-13 17:20:49 -03005246 BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005247 break;
5248 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005249
5250drop:
5251 kfree_skb(skb);
5252
5253done:
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005254 l2cap_chan_unlock(chan);
Marcel Holtmann01394182006-07-03 10:02:46 +02005255
Linus Torvalds1da177e2005-04-16 15:20:36 -07005256 return 0;
5257}
5258
Al Viro8e036fc2007-07-29 00:16:36 -07005259static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005260{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005261 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005262
Ido Yarivc2287682012-04-20 15:46:07 -03005263 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005264 if (!chan)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005265 goto drop;
5266
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005267 BT_DBG("chan %p, len %d", chan, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005268
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005269 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005270 goto drop;
5271
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005272 if (chan->imtu < skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005273 goto drop;
5274
Gustavo F. Padovan23070492011-05-16 17:57:22 -03005275 if (!chan->ops->recv(chan->data, skb))
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005276 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005277
5278drop:
5279 kfree_skb(skb);
5280
Linus Torvalds1da177e2005-04-16 15:20:36 -07005281 return 0;
5282}
5283
Andrei Emeltchenkod9b88702012-03-12 12:13:08 +02005284static inline int l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
5285 struct sk_buff *skb)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005286{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005287 struct l2cap_chan *chan;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005288
Ido Yarivc2287682012-04-20 15:46:07 -03005289 chan = l2cap_global_chan_by_scid(0, cid, conn->src, conn->dst);
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005290 if (!chan)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005291 goto drop;
5292
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005293 BT_DBG("chan %p, len %d", chan, skb->len);
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005294
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005295 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005296 goto drop;
5297
Vinicius Costa Gomese13e21d2011-06-17 22:46:27 -03005298 if (chan->imtu < skb->len)
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005299 goto drop;
5300
Gustavo F. Padovan23070492011-05-16 17:57:22 -03005301 if (!chan->ops->recv(chan->data, skb))
Andrei Emeltchenko5b4ceda2012-02-24 16:35:32 +02005302 return 0;
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005303
5304drop:
5305 kfree_skb(skb);
5306
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005307 return 0;
5308}
5309
Linus Torvalds1da177e2005-04-16 15:20:36 -07005310static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
5311{
5312 struct l2cap_hdr *lh = (void *) skb->data;
Al Viro8e036fc2007-07-29 00:16:36 -07005313 u16 cid, len;
5314 __le16 psm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005315
5316 skb_pull(skb, L2CAP_HDR_SIZE);
5317 cid = __le16_to_cpu(lh->cid);
5318 len = __le16_to_cpu(lh->len);
5319
Gustavo F. Padovan1c2acff2009-08-20 22:25:57 -03005320 if (len != skb->len) {
5321 kfree_skb(skb);
5322 return;
5323 }
5324
Linus Torvalds1da177e2005-04-16 15:20:36 -07005325 BT_DBG("len %d, cid 0x%4.4x", len, cid);
5326
5327 switch (cid) {
Claudio Takahasi3300d9a2011-02-11 19:28:54 -02005328 case L2CAP_CID_LE_SIGNALING:
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005329 case L2CAP_CID_SIGNALING:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005330 l2cap_sig_channel(conn, skb);
5331 break;
5332
Gustavo F. Padovan8db4dc42009-04-20 01:31:05 -03005333 case L2CAP_CID_CONN_LESS:
Andrei Emeltchenko097db762012-03-09 14:16:17 +02005334 psm = get_unaligned((__le16 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005335 skb_pull(skb, 2);
5336 l2cap_conless_channel(conn, psm, skb);
5337 break;
5338
Gustavo F. Padovan9f69bda2011-04-07 16:40:25 -03005339 case L2CAP_CID_LE_DATA:
5340 l2cap_att_channel(conn, cid, skb);
5341 break;
5342
Anderson Brigliab501d6a2011-06-07 18:46:31 -03005343 case L2CAP_CID_SMP:
5344 if (smp_sig_channel(conn, skb))
5345 l2cap_conn_del(conn->hcon, EACCES);
5346 break;
5347
Linus Torvalds1da177e2005-04-16 15:20:36 -07005348 default:
5349 l2cap_data_channel(conn, cid, skb);
5350 break;
5351 }
5352}
5353
5354/* ---- L2CAP interface with lower layer (HCI) ---- */
5355
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005356int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005357{
5358 int exact = 0, lm1 = 0, lm2 = 0;
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005359 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005360
Linus Torvalds1da177e2005-04-16 15:20:36 -07005361 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
5362
5363 /* Find listening sockets and check their link_mode */
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005364 read_lock(&chan_list_lock);
5365 list_for_each_entry(c, &chan_list, global_l) {
5366 struct sock *sk = c->sk;
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005367
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005368 if (c->state != BT_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005369 continue;
5370
5371 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005372 lm1 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005373 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005374 lm1 |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005375 exact++;
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005376 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
5377 lm2 |= HCI_LM_ACCEPT;
Andrei Emeltchenko43bd0f32011-10-11 14:04:34 +03005378 if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
Marcel Holtmann2af6b9d2009-01-15 21:58:38 +01005379 lm2 |= HCI_LM_MASTER;
5380 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005381 }
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005382 read_unlock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005383
5384 return exact ? lm1 : lm2;
5385}
5386
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005387int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005388{
Marcel Holtmann01394182006-07-03 10:02:46 +02005389 struct l2cap_conn *conn;
5390
Linus Torvalds1da177e2005-04-16 15:20:36 -07005391 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
5392
Linus Torvalds1da177e2005-04-16 15:20:36 -07005393 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005394 conn = l2cap_conn_add(hcon, status);
5395 if (conn)
5396 l2cap_conn_ready(conn);
Marcel Holtmann01394182006-07-03 10:02:46 +02005397 } else
Joe Perchese1750722011-06-29 18:18:29 -07005398 l2cap_conn_del(hcon, bt_to_errno(status));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005399
5400 return 0;
5401}
5402
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005403int l2cap_disconn_ind(struct hci_conn *hcon)
Marcel Holtmann2950f212009-02-12 14:02:50 +01005404{
5405 struct l2cap_conn *conn = hcon->l2cap_data;
5406
5407 BT_DBG("hcon %p", hcon);
5408
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005409 if (!conn)
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02005410 return HCI_ERROR_REMOTE_USER_TERM;
Marcel Holtmann2950f212009-02-12 14:02:50 +01005411 return conn->disc_reason;
5412}
5413
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005414int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005415{
5416 BT_DBG("hcon %p reason %d", hcon, reason);
5417
Joe Perchese1750722011-06-29 18:18:29 -07005418 l2cap_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005419 return 0;
5420}
5421
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005422static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005423{
Gustavo F. Padovan715ec002011-05-02 17:13:55 -03005424 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
Marcel Holtmann255c7602009-02-04 21:07:19 +01005425 return;
5426
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005427 if (encrypt == 0x00) {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005428 if (chan->sec_level == BT_SECURITY_MEDIUM) {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005429 __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005430 } else if (chan->sec_level == BT_SECURITY_HIGH)
Gustavo F. Padovan0f852722011-05-04 19:42:50 -03005431 l2cap_chan_close(chan, ECONNREFUSED);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005432 } else {
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005433 if (chan->sec_level == BT_SECURITY_MEDIUM)
Gustavo F. Padovanc9b66672011-05-17 14:59:01 -03005434 __clear_chan_timer(chan);
Marcel Holtmannf62e4322009-01-15 21:58:44 +01005435 }
5436}
5437
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005438int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005439{
Marcel Holtmann40be4922008-07-14 20:13:50 +02005440 struct l2cap_conn *conn = hcon->l2cap_data;
Gustavo F. Padovan48454072011-03-25 00:22:30 -03005441 struct l2cap_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005442
Marcel Holtmann01394182006-07-03 10:02:46 +02005443 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005444 return 0;
Marcel Holtmann01394182006-07-03 10:02:46 +02005445
Linus Torvalds1da177e2005-04-16 15:20:36 -07005446 BT_DBG("conn %p", conn);
5447
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005448 if (hcon->type == LE_LINK) {
Hemant Gupta35d4adcc2012-04-18 14:46:26 +05305449 if (!status && encrypt)
5450 smp_distribute_keys(conn, 0);
Ulisses Furquim17cd3f32012-01-30 18:26:28 -02005451 cancel_delayed_work(&conn->security_timer);
Vinicius Costa Gomes160dc6a2011-08-19 21:06:55 -03005452 }
5453
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005454 mutex_lock(&conn->chan_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005455
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005456 list_for_each_entry(chan, &conn->chan_l, list) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005457 l2cap_chan_lock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005458
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005459 BT_DBG("chan->scid %d", chan->scid);
5460
5461 if (chan->scid == L2CAP_CID_LE_DATA) {
5462 if (!status && encrypt) {
5463 chan->sec_level = hcon->sec_level;
Andrei Emeltchenkocf4cd002012-02-06 15:03:59 +02005464 l2cap_chan_ready(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005465 }
5466
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005467 l2cap_chan_unlock(chan);
Vinicius Costa Gomesf1cb9af2011-01-26 21:42:57 -03005468 continue;
5469 }
5470
Gustavo F. Padovanc1360a12011-06-10 17:02:12 -03005471 if (test_bit(CONF_CONNECT_PEND, &chan->conf_state)) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005472 l2cap_chan_unlock(chan);
Marcel Holtmann6a8d3012009-02-06 23:56:36 +01005473 continue;
5474 }
5475
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005476 if (!status && (chan->state == BT_CONNECTED ||
5477 chan->state == BT_CONFIG)) {
Gustavo Padovana7d77232012-05-13 03:20:07 -03005478 struct sock *sk = chan->sk;
5479
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005480 clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
Gustavo Padovana7d77232012-05-13 03:20:07 -03005481 sk->sk_state_change(sk);
5482
Gustavo F. Padovan43434782011-04-12 18:31:57 -03005483 l2cap_check_encryption(chan, encrypt);
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005484 l2cap_chan_unlock(chan);
Marcel Holtmann9719f8a2008-07-14 20:13:45 +02005485 continue;
5486 }
5487
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005488 if (chan->state == BT_CONNECT) {
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005489 if (!status) {
Andrei Emeltchenko9b27f352012-02-24 16:00:00 +02005490 l2cap_send_conn_req(chan);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005491 } else {
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005492 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005493 }
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005494 } else if (chan->state == BT_CONNECT2) {
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005495 struct sock *sk = chan->sk;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005496 struct l2cap_conn_rsp rsp;
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005497 __u16 res, stat;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005498
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005499 lock_sock(sk);
5500
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005501 if (!status) {
Gustavo Padovanc5daa682012-05-16 12:17:10 -03005502 if (test_bit(BT_SK_DEFER_SETUP,
5503 &bt_sk(sk)->flags)) {
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005504 struct sock *parent = bt_sk(sk)->parent;
5505 res = L2CAP_CR_PEND;
5506 stat = L2CAP_CS_AUTHOR_PEND;
Ilia Kolomisnky05e9a2f2011-07-15 18:30:21 +00005507 if (parent)
5508 parent->sk_data_ready(parent, 0);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005509 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005510 __l2cap_state_change(chan, BT_CONFIG);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005511 res = L2CAP_CR_SUCCESS;
5512 stat = L2CAP_CS_NO_INFO;
5513 }
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005514 } else {
Andrei Emeltchenko0e587be2012-02-21 12:54:57 +02005515 __l2cap_state_change(chan, BT_DISCONN);
Marcel Holtmannba13ccd2012-03-01 14:25:33 -08005516 __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005517 res = L2CAP_CR_SEC_BLOCK;
5518 stat = L2CAP_CS_NO_INFO;
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005519 }
5520
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005521 release_sock(sk);
5522
Gustavo F. Padovanfe4128e2011-04-13 19:50:45 -03005523 rsp.scid = cpu_to_le16(chan->dcid);
5524 rsp.dcid = cpu_to_le16(chan->scid);
Johan Hedbergdf3c3932011-06-14 12:48:19 +03005525 rsp.result = cpu_to_le16(res);
5526 rsp.status = cpu_to_le16(stat);
Gustavo F. Padovanfc7f8a72011-03-25 13:59:37 -03005527 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
5528 sizeof(rsp), &rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005529 }
5530
Andrei Emeltchenko6be36552012-02-22 17:11:56 +02005531 l2cap_chan_unlock(chan);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005532 }
5533
Andrei Emeltchenko3df91ea2012-02-21 12:54:55 +02005534 mutex_unlock(&conn->chan_lock);
Marcel Holtmannb1235d72008-07-14 20:13:54 +02005535
Linus Torvalds1da177e2005-04-16 15:20:36 -07005536 return 0;
5537}
5538
Ulisses Furquim686ebf22011-12-21 10:11:33 -02005539int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005540{
5541 struct l2cap_conn *conn = hcon->l2cap_data;
5542
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02005543 if (!conn)
5544 conn = l2cap_conn_add(hcon, 0);
5545
5546 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005547 goto drop;
5548
5549 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
5550
Andrei Emeltchenkoe7021122011-01-03 11:14:36 +02005551 if (!(flags & ACL_CONT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005552 struct l2cap_hdr *hdr;
5553 int len;
5554
5555 if (conn->rx_len) {
5556 BT_ERR("Unexpected start frame (len %d)", skb->len);
5557 kfree_skb(conn->rx_skb);
5558 conn->rx_skb = NULL;
5559 conn->rx_len = 0;
5560 l2cap_conn_unreliable(conn, ECOMM);
5561 }
5562
Andrei Emeltchenkoaae7fe22010-09-15 14:28:43 +03005563 /* Start fragment always begin with Basic L2CAP header */
5564 if (skb->len < L2CAP_HDR_SIZE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005565 BT_ERR("Frame is too short (len %d)", skb->len);
5566 l2cap_conn_unreliable(conn, ECOMM);
5567 goto drop;
5568 }
5569
5570 hdr = (struct l2cap_hdr *) skb->data;
5571 len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
5572
5573 if (len == skb->len) {
5574 /* Complete frame received */
5575 l2cap_recv_frame(conn, skb);
5576 return 0;
5577 }
5578
5579 BT_DBG("Start: total len %d, frag len %d", len, skb->len);
5580
5581 if (skb->len > len) {
5582 BT_ERR("Frame is too long (len %d, expected len %d)",
5583 skb->len, len);
5584 l2cap_conn_unreliable(conn, ECOMM);
5585 goto drop;
5586 }
5587
5588 /* Allocate skb for the complete frame (with header) */
Gustavo F. Padovanaf05b30b2009-04-20 01:31:08 -03005589 conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
5590 if (!conn->rx_skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005591 goto drop;
5592
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005593 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01005594 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005595 conn->rx_len = len - skb->len;
5596 } else {
5597 BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
5598
5599 if (!conn->rx_len) {
5600 BT_ERR("Unexpected continuation frame (len %d)", skb->len);
5601 l2cap_conn_unreliable(conn, ECOMM);
5602 goto drop;
5603 }
5604
5605 if (skb->len > conn->rx_len) {
5606 BT_ERR("Fragment is too long (len %d, expected %d)",
5607 skb->len, conn->rx_len);
5608 kfree_skb(conn->rx_skb);
5609 conn->rx_skb = NULL;
5610 conn->rx_len = 0;
5611 l2cap_conn_unreliable(conn, ECOMM);
5612 goto drop;
5613 }
5614
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03005615 skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
Marcel Holtmanne1027a72009-02-09 09:18:02 +01005616 skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005617 conn->rx_len -= skb->len;
5618
5619 if (!conn->rx_len) {
5620 /* Complete frame received */
5621 l2cap_recv_frame(conn, conn->rx_skb);
5622 conn->rx_skb = NULL;
5623 }
5624 }
5625
5626drop:
5627 kfree_skb(skb);
5628 return 0;
5629}
5630
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005631static int l2cap_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005632{
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005633 struct l2cap_chan *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005634
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005635 read_lock(&chan_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005636
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005637 list_for_each_entry(c, &chan_list, global_l) {
5638 struct sock *sk = c->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005639
Gustavo F. Padovan903d3432011-02-10 14:16:06 -02005640 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005641 batostr(&bt_sk(sk)->src),
5642 batostr(&bt_sk(sk)->dst),
Gustavo F. Padovan89bc5002011-06-03 00:19:47 -03005643 c->state, __le16_to_cpu(c->psm),
Gustavo F. Padovan23691d72011-04-27 18:26:32 -03005644 c->scid, c->dcid, c->imtu, c->omtu,
5645 c->sec_level, c->mode);
Andrei Emeltchenko61e1b4b2012-01-19 11:19:50 +02005646 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005647
Gustavo F. Padovan333055f2011-12-22 15:14:39 -02005648 read_unlock(&chan_list_lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005649
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005650 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005651}
5652
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005653static int l2cap_debugfs_open(struct inode *inode, struct file *file)
5654{
5655 return single_open(file, l2cap_debugfs_show, inode->i_private);
5656}
5657
5658static const struct file_operations l2cap_debugfs_fops = {
5659 .open = l2cap_debugfs_open,
5660 .read = seq_read,
5661 .llseek = seq_lseek,
5662 .release = single_release,
5663};
5664
5665static struct dentry *l2cap_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005666
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005667int __init l2cap_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005668{
5669 int err;
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08005670
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005671 err = l2cap_init_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005672 if (err < 0)
5673 return err;
5674
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005675 if (bt_debugfs) {
5676 l2cap_debugfs = debugfs_create_file("l2cap", 0444,
5677 bt_debugfs, NULL, &l2cap_debugfs_fops);
5678 if (!l2cap_debugfs)
5679 BT_ERR("Failed to create L2CAP debug file");
5680 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005681
Linus Torvalds1da177e2005-04-16 15:20:36 -07005682 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005683}
5684
Gustavo F. Padovan64274512011-02-07 20:08:52 -02005685void l2cap_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005686{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01005687 debugfs_remove(l2cap_debugfs);
Gustavo F. Padovanbb58f742011-02-03 20:50:35 -02005688 l2cap_cleanup_sockets();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005689}
5690
Gustavo F. Padovand1c4a172010-07-18 16:25:54 -03005691module_param(disable_ertm, bool, 0644);
5692MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");